{"record":{"id":"c69142d83df93416","repo":"jackwener/OpenCLI","slug":"result-error-unknown-tm","errorCode":null,"errorMessage":"视频文件注入失败: ${result?.error ?? 'unknown'}\n截图已保存到 /tmp/wechat-channels_publish_upload_debug.png","messagePattern":"视频文件注入失败: (.+?)\n截图已保存到 /tmp/wechat-channels_publish_upload_debug\\.png","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/wechat-channels/publish.js","lineNumber":259,"sourceCode":"        var binary = atob(b64);\n        var bytes = new Uint8Array(binary.length);\n        for (var i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n        var dt = new DataTransfer();\n        dt.items.add(new File([bytes], params.fileName, { type: params.mimeType }));\n        Object.defineProperty(input, 'files', { value: dt.files, configurable: true });\n        input.dispatchEvent(new Event('change', { bubbles: true }));\n        input.dispatchEvent(new Event('input',  { bubbles: true }));\n        return { ok: true };\n      } catch(e) {\n        window.__oc_chunks = [];\n        return { ok: false, error: e.message };\n      }\n    })(${JSON.stringify({ fileName, mimeType })})\n  `);\n\n  if (!result?.ok) {\n    await page.screenshot({ path: '/tmp/wechat-channels_publish_upload_debug.png' });\n    throw new CommandExecutionError(`视频文件注入失败: ${result?.error ?? 'unknown'}\\n截图已保存到 /tmp/wechat-channels_publish_upload_debug.png`);\n  }\n}\n\n// ── Helper: wait for upload + transcode completion ───────────────────────────\nasync function waitForUploadDone(page, fileName, maxMs = 180_000) {\n  const pollMs = 3_000;\n  const maxAttempts = Math.ceil(maxMs / pollMs);\n\n  for (let i = 0; i < maxAttempts; i++) {\n    let done;\n    try {\n      done = await evalPage(page, `\n        ((fileName) => {\n          ${DEEP_QUERY_FN}\n          var root = wujieRoot() || document;\n          var bodyText = (root.innerText || root.textContent || '').trim();\n          var uploading = deepQuery('[class*=\"upload\"][class*=\"progress\"]') ||\n                          deepQuery('[class*=\"uploading\"]') ||","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/wechat-channels/publish.js#L241-L277","documentation":"uploadFile injects the video file into the page's file input via CDP/in-page DataTransfer. If the injected script reports ok:false, a debug screenshot is saved to /tmp/wechat-channels_publish_upload_debug.png and a CommandExecutionError is thrown with the script's error reason. This usually means the file input or upload trigger was not reachable in the wujie shadow DOM, or the in-page injection itself failed.","triggerScenarios":"Upload trigger selectors no longer match after a WeChat UI change; the creator page failed to render (login expired, wujie micro-frontend error); the in-page evaluate threw or returned an unexpected shape (result.error set by the script).","commonSituations":"WeChat updated the creator-center DOM; session not logged in so the create page redirected; Chrome/CDP version mismatch breaking setFileInput.","solutions":["Inspect /tmp/wechat-channels_publish_upload_debug.png to see what the page actually rendered.","Confirm you are logged into channels.weixin.qq.com in the driven Chrome instance and the create page loads.","Retry once — transient render/timing issues can cause the input to be missing.","If the DOM changed, update UPLOAD_TRIGGER_SELECTORS / injection script in clis/wechat-channels/publish.js to match the new markup."],"exampleFix":"// before (stale selector)\nconst UPLOAD_TRIGGER_SELECTORS = ['span.add-icon.weui-icon-outlined-add'];\n// after (add new markup observed in debug screenshot)\nconst UPLOAD_TRIGGER_SELECTORS = ['span.add-icon.weui-icon-outlined-add', '.new-upload-entry', 'div.upload-content'];","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  await publish({ videoPath });\n} catch (e) {\n  if (/视频文件注入失败/.test(e.message)) {\n    // check the debug screenshot, re-login if needed, then retry once\n    await ensureLoggedIn();\n    return publish({ videoPath });\n  }\n  throw e;\n}","preventionTips":["Keep the driven Chrome session logged into channels.weixin.qq.com.","Check /tmp/wechat-channels_publish_upload_debug.png immediately after a failure.","After WeChat UI updates, re-verify upload trigger selectors before batch publishing."],"tags":["browser-automation","shadow-dom","upload"],"backgroundTag":"dom-injection-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}