jackwener/OpenCLI · error · CommandExecutionError

视频文件注入失败: ${result?.error ?? 'unknown'} 截图已保存到 /tmp/wechat-c

Error message

视频文件注入失败: ${result?.error ?? 'unknown'}
截图已保存到 /tmp/wechat-channels_publish_upload_debug.png

What it means

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.

Source

Thrown at clis/wechat-channels/publish.js:259

        var binary = atob(b64);
        var bytes = new Uint8Array(binary.length);
        for (var i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
        var dt = new DataTransfer();
        dt.items.add(new File([bytes], params.fileName, { type: params.mimeType }));
        Object.defineProperty(input, 'files', { value: dt.files, configurable: true });
        input.dispatchEvent(new Event('change', { bubbles: true }));
        input.dispatchEvent(new Event('input',  { bubbles: true }));
        return { ok: true };
      } catch(e) {
        window.__oc_chunks = [];
        return { ok: false, error: e.message };
      }
    })(${JSON.stringify({ fileName, mimeType })})
  `);

  if (!result?.ok) {
    await page.screenshot({ path: '/tmp/wechat-channels_publish_upload_debug.png' });
    throw new CommandExecutionError(`视频文件注入失败: ${result?.error ?? 'unknown'}\n截图已保存到 /tmp/wechat-channels_publish_upload_debug.png`);
  }
}

// ── Helper: wait for upload + transcode completion ───────────────────────────
async function waitForUploadDone(page, fileName, maxMs = 180_000) {
  const pollMs = 3_000;
  const maxAttempts = Math.ceil(maxMs / pollMs);

  for (let i = 0; i < maxAttempts; i++) {
    let done;
    try {
      done = await evalPage(page, `
        ((fileName) => {
          ${DEEP_QUERY_FN}
          var root = wujieRoot() || document;
          var bodyText = (root.innerText || root.textContent || '').trim();
          var uploading = deepQuery('[class*="upload"][class*="progress"]') ||
                          deepQuery('[class*="uploading"]') ||

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect /tmp/wechat-channels_publish_upload_debug.png to see what the page actually rendered.
  2. Confirm you are logged into channels.weixin.qq.com in the driven Chrome instance and the create page loads.
  3. Retry once — transient render/timing issues can cause the input to be missing.
  4. If the DOM changed, update UPLOAD_TRIGGER_SELECTORS / injection script in clis/wechat-channels/publish.js to match the new markup.

Example fix

// before (stale selector)
const UPLOAD_TRIGGER_SELECTORS = ['span.add-icon.weui-icon-outlined-add'];
// after (add new markup observed in debug screenshot)
const UPLOAD_TRIGGER_SELECTORS = ['span.add-icon.weui-icon-outlined-add', '.new-upload-entry', 'div.upload-content'];
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

try {
  await publish({ videoPath });
} catch (e) {
  if (/视频文件注入失败/.test(e.message)) {
    // check the debug screenshot, re-login if needed, then retry once
    await ensureLoggedIn();
    return publish({ videoPath });
  }
  throw e;
}

Prevention

When it happens

Trigger: 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).

Common situations: WeChat updated the creator-center DOM; session not logged in so the create page redirected; Chrome/CDP version mismatch breaking setFileInput.

Related errors


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