{"record":{"id":"a3919c7d3eb20220","repo":"jackwener/OpenCLI","slug":"wechat-image-upload-failed-message","errorCode":null,"errorMessage":"WeChat image upload failed: ${message}","messagePattern":"WeChat image upload failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/weixin/create-draft.js","lineNumber":121,"sourceCode":"        return Array.from(editor.querySelectorAll('img')).map(function(img) {\n            return img.getAttribute('data-src') || img.getAttribute('src') || '';\n        }).filter(function(src) { return /(?:mmbiz|qpic\\\\.cn)/i.test(src); });\n    })()`);\n    if (!Array.isArray(keys)) {\n        throw new CommandExecutionError('WeChat image upload returned a malformed editor image payload.');\n    }\n    return keys.map(String);\n}\n\nasync function injectImageFile(page, image) {\n    if (typeof page.setFileInput === 'function') {\n        try {\n            await page.setFileInput([image.absPath], IMAGE_FILE_INPUT_SELECTOR);\n            return;\n        } catch (error) {\n            if (!isRecoverableFileInputError(error)) {\n                const message = error instanceof Error ? error.message : String(error);\n                throw new CommandExecutionError(`WeChat image upload failed: ${message}`);\n            }\n        }\n    }\n\n    const base64 = fs.readFileSync(image.absPath).toString('base64');\n    const fallback = await evaluate(page, `(() => {\n        var input = document.querySelector(${JSON.stringify(IMAGE_FILE_INPUT_SELECTOR)});\n        if (!input) return { ok: false, reason: 'image file input not found' };\n        try {\n            var binary = atob(${JSON.stringify(base64)});\n            var bytes = new Uint8Array(binary.length);\n            for (var i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n            var transfer = new DataTransfer();\n            transfer.items.add(new File([bytes], ${JSON.stringify(image.fileName)}, { type: ${JSON.stringify(image.mimeType)} }));\n            var descriptor = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'files');\n            if (descriptor && descriptor.set) descriptor.set.call(input, transfer.files);\n            else input.files = transfer.files;\n            if (!input.files || input.files.length !== 1) return { ok: false, reason: 'file input rejected fallback file' };","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weixin/create-draft.js#L103-L139","documentation":"Thrown by injectImageFile when the primary upload path — setting the file input directly via page.setFileInput with the image's absolute path — fails with an error the library does not classify as recoverable. The original error message is wrapped into this CommandExecutionError.","triggerScenarios":"page.setFileInput throws because the file input selector (IMAGE_FILE_INPUT_SELECTOR) is absent, the input is hidden/detached, the driver lacks setFileInput support (but isRecoverableFileInputError deems the failure non-recoverable), or the image path is invalid and the driver rejects the file.","commonSituations":"WeChat changed the upload dialog's file input markup; the automation driver version lacks or changed setFileInput semantics; the image absPath points to a missing/unreadable file; the dialog did not open before the call.","solutions":["Verify image.absPath exists and is a readable image file before calling the command.","Ensure the upload dialog/file input is present before setFileInput runs (add a wait or poll for the input).","Update or fix isRecoverableFileInputError if the underlying error should fall through to the base64 fallback path instead of throwing.","Check the driver supports page.setFileInput with your image type; upgrade the automation driver if needed."],"exampleFix":"// before\ncatch (error) {\n    if (!isRecoverableFileInputError(error)) {\n        const message = error instanceof Error ? error.message : String(error);\n        throw new CommandExecutionError(`WeChat image upload failed: ${message}`);\n    }\n}\n// after\ncatch (error) {\n    if (!isRecoverableFileInputError(error) && !isMissingFileInputError(error)) {\n        const message = error instanceof Error ? error.message : String(error);\n        throw new CommandExecutionError(`WeChat image upload failed: ${message}`);\n    }\n    // otherwise fall through to base64 evaluate() fallback\n}","handlingStrategy":"fallback","validationCode":"const fs = require('fs');\nif (!fs.existsSync(image.absPath)) throw new Error(`image missing: ${image.absPath}`);\nif (fs.statSync(image.absPath).size === 0) throw new Error(`image is empty: ${image.absPath}`);","typeGuard":"function hasSetFileInput(page) { return typeof page.setFileInput === 'function'; }","tryCatchPattern":"try {\n    await createDraftCommand(opts);\n} catch (e) {\n    if (/WeChat image upload failed:/i.test(e.message)) {\n        console.error('setFileInput path failed:', e.message);\n        // ensure image path/format are valid, then retry\n    }\n    throw e;\n}","preventionTips":["Verify image files exist, are non-empty, and are JPEG/PNG before running.","Keep the automation driver up to date so setFileInput semantics match.","Ensure the upload dialog is open before file injection.","Treat driver API changes (setFileInput) as a first suspect when this appears after an upgrade."],"tags":["wechat","file-upload","automation","image"],"backgroundTag":"file-upload-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}