jackwener/OpenCLI · error · CommandExecutionError

Could not select WeChat image upload: ${selected?.reason ||

Error message

Could not select WeChat image upload: ${selected?.reason || 'unknown error'}

What it means

Thrown by uploadContentImage after the insert-image button is clicked but the in-page script cannot find and click the upload menu item inside the image dropdown (.js_img_dropdown_menu .tpl_dropdown_menu_item). The failure reason from the page script is included in the message.

Source

Thrown at clis/weixin/create-draft.js:169

async function uploadContentImage(page, image) {
    const previousKeys = await readCdnImageKeys(page);
    const opened = await evaluate(page, `(() => {
        var button = document.querySelector('#js_editor_insertimage');
        if (!button) return { ok: false, reason: 'insert-image button not found' };
        button.click();
        return { ok: true };
    })()`);
    if (!opened?.ok) throw new CommandExecutionError(`Could not open WeChat image upload: ${opened?.reason || 'unknown error'}`);
    await page.wait(1);

    const selected = await evaluate(page, `(() => {
        var item = document.querySelector('.js_img_dropdown_menu .tpl_dropdown_menu_item');
        if (!item) return { ok: false, reason: 'upload menu item not found' };
        item.click();
        return { ok: true };
    })()`);
    if (!selected?.ok) throw new CommandExecutionError(`Could not select WeChat image upload: ${selected?.reason || 'unknown error'}`);
    await page.wait(1);
    await injectImageFile(page, image);

    for (let attempt = 0; attempt < 15; attempt++) {
        await page.wait(2);
        const state = await evaluate(page, `(() => {
            var previous = new Set(${JSON.stringify(previousKeys)});
            var editor = document.querySelector('#ueditor_0');
            var images = editor ? Array.from(editor.querySelectorAll('img')) : [];
            var key = images.map(function(img) {
                return img.getAttribute('data-src') || img.getAttribute('src') || '';
            }).find(function(src) { return /(?:mmbiz|qpic\\.cn)/i.test(src) && !previous.has(src); });
            var errorText = Array.from(document.querySelectorAll('.weui-desktop-tips, .weui-desktop-toast, .js_msgSenderTips'))
                .filter(function(el) { return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); })
                .map(function(el) { return (el.innerText || el.textContent || '').trim(); })
                .filter(Boolean).join('\\n');
            return { ok: !!key, errorText: errorText };
        })()`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Increase the wait after clicking the insert-image button, or poll for the dropdown menu item instead of a fixed 1-second wait.
  2. Inspect the live editor DOM and update the .js_img_dropdown_menu .tpl_dropdown_menu_item selector if WeChat renamed classes.
  3. Retry the whole uploadContentImage sequence once; transient dropdown timing issues often resolve on retry.
  4. Check for overlays/modals on the page that could intercept the dropdown item click.

Example fix

// before
await page.wait(1);
await injectImageFile(page, image);
// after
let selected = null;
for (let i = 0; i < 5; i++) {
    await page.wait(1);
    selected = await evaluate(page, `(() => {
        var item = document.querySelector('.js_img_dropdown_menu .tpl_dropdown_menu_item');
        if (!item) return { ok: false, reason: 'upload menu item not found' };
        item.click();
        return { ok: true };
    })()`);
    if (selected?.ok) break;
}
if (!selected?.ok) throw new CommandExecutionError(`Could not select WeChat image upload: ${selected?.reason || 'unknown error'}`);
Defensive patterns

Strategy: retry

Validate before calling

await page.wait(2); // allow dropdown to render before selection
const menuReady = await evaluate(page, '!!document.querySelector(".js_img_dropdown_menu .tpl_dropdown_menu_item")');
if (menuReady !== true) throw new Error('image upload dropdown not ready');

Type guard

function isSelectResult(v) { return typeof v === 'object' && v !== null && typeof v.ok === 'boolean'; }

Try / catch

try {
    await createDraftCommand(opts);
} catch (e) {
    if (/Could not select WeChat image upload/i.test(e.message)) {
        return createDraftCommand(opts); // dropdown timing is often transient
    }
    throw e;
}

Prevention

When it happens

Trigger: The dropdown did not open (the 1-second wait was too short or the click didn't register), WeChat changed the .js_img_dropdown_menu/.tpl_dropdown_menu_item class names, the dropdown rendered but its menu items load asynchronously, or a stale overlay intercepts the click.

Common situations: Slow page/rendering environments (CI, headless) where 1 second is not enough for the dropdown; WeChat front-end refactor renaming dropdown classes; animations/overlays swallowing clicks.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/940769a0db7b6333. Report an issue: GitHub.