jackwener/OpenCLI · error · CommandExecutionError

xiaohongshu creator-note-detail: failed to read signed datac

Error message

xiaohongshu creator-note-detail: failed to read signed datacenter/note capture buffer

What it means

captureNoteDetailPayload throws this CommandExecutionError when page.evaluate('JSON.stringify(window.__xhsCapture || {})') itself rejects (or JSON.parse of the returned string fails). This means the CLI could not even read the capture buffer from the page — the execution context is gone or the page is not scriptable, distinct from the buffer merely being malformed.

Source

Thrown at clis/xiaohongshu/creator-note-detail.js:397

    // SPA-navigate inside the dashboard so the React router re-fires the
    // signed datacenter/note/* requests under our hook. A second page.goto
    // would wipe the hook before the first auto-fetch can land.
    await page.evaluate(`(() => {
    const target = '/statistics/note-detail?noteId=' + ${JSON.stringify(noteId)};
    history.pushState({}, '', target);
    window.dispatchEvent(new PopStateEvent('popstate'));
  })()`);
    const wantedSuffixes = DETAIL_API_ENDPOINTS.map((endpoint) => endpoint.suffix);
    let captureMap = {};
    for (let i = 0; i < CAPTURE_POLL_ATTEMPTS; i++) {
        await page.wait(CAPTURE_POLL_INTERVAL_S);
        let raw;
        try {
            raw = await page.evaluate('JSON.stringify(window.__xhsCapture || {})');
            captureMap = typeof raw === 'string' ? JSON.parse(raw) : {};
        }
        catch {
            throw new CommandExecutionError('xiaohongshu creator-note-detail: failed to read signed datacenter/note capture buffer');
        }
        if (!captureMap || typeof captureMap !== 'object' || Array.isArray(captureMap)) {
            throw new CommandExecutionError('xiaohongshu creator-note-detail: malformed signed datacenter/note capture buffer');
        }
        const captured = wantedSuffixes.filter((suffix) => findCapturedUrl(captureMap, suffix));
        if (captured.length === wantedSuffixes.length)
            break;
    }
    const payload = {};
    for (const endpoint of DETAIL_API_ENDPOINTS) {
        const matchUrl = findCapturedUrl(captureMap, endpoint.suffix);
        if (!matchUrl)
            continue;
        payload[endpoint.key] = parseCapturedJson(captureMap[matchUrl], endpoint);
    }
    return Object.keys(payload).length > 0 ? payload : null;
}
async function captureNoteDetailDomData(page) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the command with a fresh tab so the hook is installed after any initial redirects complete.
  2. Pre-login to creator.xiaohongshu.com first, so no mid-run redirect to the login page destroys the context.
  3. Retry — transient renderer/DevTools failures often succeed on a second run.
  4. Slow down or increase CAPTURE_POLL tolerance in your wrapper if large pages keep navigating during polling.
  5. Check Chrome/automation health (tab count, memory) if it reproduces consistently.

Example fix

// before
const rows = await run('xiaohongshu creator-note-detail', { 'note-id': id });
// after
try {
  const rows = await run('xiaohongshu creator-note-detail', { 'note-id': id });
} catch (e) {
  if (/failed to read signed .* capture buffer/.test(e.message)) {
    await newTabAt('https://creator.xiaohongshu.com/new/home');
    return await run('xiaohongshu creator-note-detail', { 'note-id': id });
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

// ensure the tab is alive and on the creator domain before invoking
if (!tab.url.startsWith('https://creator.xiaohongshu.com')) await tab.goto('https://creator.xiaohongshu.com/new/home');

Type guard

function isPlainCaptureMap(v) {
  return typeof v === 'object' && v !== null && !Array.isArray(v);
}

Try / catch

async function withRetry(fn, n = 2) {
  for (let i = 0; ; i++) {
    try { return await fn(); }
    catch (e) {
      if (i >= n || !/capture buffer/.test(e.message)) throw e;
      await sleep(2000);
    }
  }
}

Prevention

When it happens

Trigger: The page navigated/reloaded between hook installation and polling, destroying the JS context (execution context destroyed); the tab crashed or was closed; page.evaluate was rejected because the SPA hard-navigated instead of using history.pushState; the browser connection dropped.

Common situations: Xiaohongshu served a full-page redirect (e.g. to login or verification) that wiped the context mid-poll; long poll loop outlived a navigation; Chrome under automation ran out of memory and the renderer crashed; network hiccup dropped the DevTools connection.

Related errors


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