{"record":{"id":"940769a0db7b6333","repo":"jackwener/OpenCLI","slug":"could-not-select-wechat-image-upload-selected","errorCode":null,"errorMessage":"Could not select WeChat image upload: ${selected?.reason || 'unknown error'}","messagePattern":"Could not select WeChat image upload: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/weixin/create-draft.js","lineNumber":169,"sourceCode":"\nasync function uploadContentImage(page, image) {\n    const previousKeys = await readCdnImageKeys(page);\n    const opened = await evaluate(page, `(() => {\n        var button = document.querySelector('#js_editor_insertimage');\n        if (!button) return { ok: false, reason: 'insert-image button not found' };\n        button.click();\n        return { ok: true };\n    })()`);\n    if (!opened?.ok) throw new CommandExecutionError(`Could not open WeChat image upload: ${opened?.reason || 'unknown error'}`);\n    await page.wait(1);\n\n    const selected = await evaluate(page, `(() => {\n        var item = document.querySelector('.js_img_dropdown_menu .tpl_dropdown_menu_item');\n        if (!item) return { ok: false, reason: 'upload menu item not found' };\n        item.click();\n        return { ok: true };\n    })()`);\n    if (!selected?.ok) throw new CommandExecutionError(`Could not select WeChat image upload: ${selected?.reason || 'unknown error'}`);\n    await page.wait(1);\n    await injectImageFile(page, image);\n\n    for (let attempt = 0; attempt < 15; attempt++) {\n        await page.wait(2);\n        const state = await evaluate(page, `(() => {\n            var previous = new Set(${JSON.stringify(previousKeys)});\n            var editor = document.querySelector('#ueditor_0');\n            var images = editor ? Array.from(editor.querySelectorAll('img')) : [];\n            var key = images.map(function(img) {\n                return img.getAttribute('data-src') || img.getAttribute('src') || '';\n            }).find(function(src) { return /(?:mmbiz|qpic\\\\.cn)/i.test(src) && !previous.has(src); });\n            var errorText = Array.from(document.querySelectorAll('.weui-desktop-tips, .weui-desktop-toast, .js_msgSenderTips'))\n                .filter(function(el) { return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); })\n                .map(function(el) { return (el.innerText || el.textContent || '').trim(); })\n                .filter(Boolean).join('\\\\n');\n            return { ok: !!key, errorText: errorText };\n        })()`);","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weixin/create-draft.js#L151-L187","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Increase the wait after clicking the insert-image button, or poll for the dropdown menu item instead of a fixed 1-second wait.","Inspect the live editor DOM and update the .js_img_dropdown_menu .tpl_dropdown_menu_item selector if WeChat renamed classes.","Retry the whole uploadContentImage sequence once; transient dropdown timing issues often resolve on retry.","Check for overlays/modals on the page that could intercept the dropdown item click."],"exampleFix":"// before\nawait page.wait(1);\nawait injectImageFile(page, image);\n// after\nlet selected = null;\nfor (let i = 0; i < 5; i++) {\n    await page.wait(1);\n    selected = await evaluate(page, `(() => {\n        var item = document.querySelector('.js_img_dropdown_menu .tpl_dropdown_menu_item');\n        if (!item) return { ok: false, reason: 'upload menu item not found' };\n        item.click();\n        return { ok: true };\n    })()`);\n    if (selected?.ok) break;\n}\nif (!selected?.ok) throw new CommandExecutionError(`Could not select WeChat image upload: ${selected?.reason || 'unknown error'}`);","handlingStrategy":"retry","validationCode":"await page.wait(2); // allow dropdown to render before selection\nconst menuReady = await evaluate(page, '!!document.querySelector(\".js_img_dropdown_menu .tpl_dropdown_menu_item\")');\nif (menuReady !== true) throw new Error('image upload dropdown not ready');","typeGuard":"function isSelectResult(v) { return typeof v === 'object' && v !== null && typeof v.ok === 'boolean'; }","tryCatchPattern":"try {\n    await createDraftCommand(opts);\n} catch (e) {\n    if (/Could not select WeChat image upload/i.test(e.message)) {\n        return createDraftCommand(opts); // dropdown timing is often transient\n    }\n    throw e;\n}","preventionTips":["Add polling rather than fixed 1-second waits for dropdown rendering.","Re-check dropdown class names after WeChat editor updates.","Retry the upload sequence once on this error.","Run in non-headless mode once to confirm dropdown behavior matches headless."],"tags":["wechat","dom-parsing","editor-ui","timing"],"backgroundTag":"selector-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}