jackwener/OpenCLI · error

Could not prepare ${fieldName} input. Debug screenshot: /tmp

Error message

Could not prepare ${fieldName} input. Debug screenshot: /tmp/xhs_publish_${fieldName}_debug.png

What it means

Thrown by fillField when the 'prepare' phase (focusing the located input and firing beforeinput events) fails — prepared.ok was falsy — meaning the editor element was found but could not be put into a state to receive text. A debug screenshot is saved first.

Source

Thrown at clis/xiaohongshu/publish.js:367

          }
        };
        const el = Array.from(document.querySelectorAll(selector)).find(node => node && node.offsetParent !== null);
        if (!el) return { ok: false };
        el.focus();
        el.textContent = '';
        const selection = window.getSelection();
        const range = document.createRange();
        range.selectNodeContents(el);
        range.collapse(false);
        selection?.removeAllRanges();
        selection?.addRange(range);
        fireBeforeInput(el, nextText);
        return { ok: true };
      })(${JSON.stringify(located.sel)}, ${JSON.stringify(text)})
    `);
        if (!prepared?.ok) {
            await page.screenshot({ path: `/tmp/xhs_publish_${fieldName}_debug.png` });
            throw new Error(`Could not prepare ${fieldName} input. Debug screenshot: /tmp/xhs_publish_${fieldName}_debug.png`);
        }
        try {
            await page.insertText(text);
            result = await page.evaluate(`
      ((selector, expectedText) => {
        const __opencli_xhs_fill_phase = "verify";
        const normalize = (value) => (value || '').replace(/\\s+/g, ' ').trim();
        const fireInput = (el, value) => {
          try {
            el.dispatchEvent(new InputEvent('input', {
              bubbles: true,
              data: value,
              inputType: 'insertText',
            }));
          } catch {
            el.dispatchEvent(new Event('input', { bubbles: true }));
          }
        };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect /tmp/xhs_publish_<field>_debug.png for overlays, dialogs, or login prompts.
  2. Dismiss any modals/cookies dialogs on the publish page before publishing.
  3. Retry with longer waits so the page settles before filling.
  4. Update the CLI in case XHS changed its editor structure.

Example fix

// before
await xhs.publish({ ... }); // fails when a modal covers the editor
// after
try {
  await xhs.publish({ ... });
} catch (e) {
  if (e.message.includes('Could not prepare')) {
    // dismiss modal, then retry
    await publish();
  }
}
Defensive patterns

Strategy: retry

Validate before calling

// dismiss blocking overlays beforehand if your wrapper exposes it
await page.evaluate(() => document.querySelectorAll('.modal, .dialog').forEach(el => el.remove()));

Try / catch

try {
  await xhs.publish(opts);
} catch (err) {
  if (err.message.includes('Could not prepare')) {
    inspectScreenshot('/tmp/xhs_publish_debug.png');
    return retryPublish(opts);
  }
  throw err;
}

Prevention

When it happens

Trigger: Editor is contenteditable but focus is stolen by an overlay/modal; shadow-DOM or iframe boundary prevents the script from mutating the element; page re-rendered between locate and prepare; anti-bot script interfering with synthetic events.

Common situations: XHS shows a popup/dialog over the editor; slow page replaced DOM mid-fill; running in an unusual browser build where CDP input events behave differently.

Related errors


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