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
- Re-run the command with a fresh tab so the hook is installed after any initial redirects complete.
- Pre-login to creator.xiaohongshu.com first, so no mid-run redirect to the login page destroys the context.
- Retry — transient renderer/DevTools failures often succeed on a second run.
- Slow down or increase CAPTURE_POLL tolerance in your wrapper if large pages keep navigating during polling.
- 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
- Complete login first so no mid-run redirect destroys the page context.
- Avoid navigating or reloading the tab while the command polls for captures.
- Retry once automatically — context loss is often transient.
- Keep Chrome/tab memory pressure low during automation runs.
- Use a dedicated tab for CLI runs instead of a shared one.
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
- Failed to extract xiaoe content: ${message}
- Failed to list xiaoe courses: ${message}
- xiaohongshu creator-note-detail: signed API ${suffix} return
- xiaohongshu creator-note-detail: malformed signed datacenter
- No feed items in the hydrated store.
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/bda0a0132863d491.
Report an issue: GitHub.