{"record":{"id":"1914284cd69d101e","repo":"jackwener/OpenCLI","slug":"unexpected-evaluate-response-191428","errorCode":null,"errorMessage":"Unexpected evaluate response","messagePattern":"Unexpected evaluate response","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/xiaohongshu/note.js","lineNumber":84,"sourceCode":"    name: 'note',\n    access: 'read',\n    description: '获取小红书笔记正文和互动数据',\n    domain: 'www.xiaohongshu.com',\n    strategy: Strategy.COOKIE,\n    navigateBefore: false,\n    args: [\n        { name: 'note-id', required: true, positional: true, help: 'Full Xiaohongshu note URL with xsec_token' },\n    ],\n    columns: ['field', 'value'],\n    func: async (page, kwargs) => {\n        const raw = String(kwargs['note-id']);\n        const noteId = parseNoteId(raw);\n        const url = buildNoteUrl(raw, { commandName: 'xiaohongshu note' });\n        await page.goto(url);\n        await page.wait({ time: 2 + Math.random() * 3 });\n        const data = await page.evaluate(NOTE_EXTRACT_JS);\n        if (!data || typeof data !== 'object') {\n            throw new EmptyResultError('xiaohongshu/note', 'Unexpected evaluate response');\n        }\n        if (data.securityBlock) {\n            throw new CliError('SECURITY_BLOCK', 'Xiaohongshu security block: the note detail page was blocked by risk control.', /^https?:\\/\\//.test(raw)\n                ? 'The page may be temporarily restricted. Try again later or from a different session.'\n                : 'Try using a full URL from search results (with xsec_token) instead of a bare note ID.');\n        }\n        if (data.loginWall) {\n            throw new AuthRequiredError('www.xiaohongshu.com', 'Note content requires login');\n        }\n        if (data.notFound) {\n            throw new EmptyResultError('xiaohongshu/note', `Note ${noteId} not found or unavailable — it may have been deleted or restricted`);\n        }\n        const d = data;\n        // XHS renders placeholder text like \"赞\"/\"收藏\"/\"评论\" when count is 0;\n        // normalize to '0' unless the value looks numeric.\n        const numOrZero = (v) => /^\\d+/.test(v) ? v : '0';\n        // A note may legitimately have no title, but a real note page always\n        // renders an author. If both are missing, the page failed to load.","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/note.js#L66-L102","documentation":"After navigating to the note page and running NOTE_EXTRACT_JS via page.evaluate, the command expects an object result. If the evaluated script returns null, undefined, or a non-object, EmptyResultError('xiaohongshu/note', 'Unexpected evaluate response') is thrown — meaning the extraction script did not produce usable data rather than the note being missing.","triggerScenarios":"page.evaluate(NOTE_EXTRACT_JS) returns a non-object — the extraction script bailed early because the page structure was unexpected, the page did not finish rendering, or evaluate returned a wrapped/unserializable value.","commonSituations":"Slow network so the SPA hadn't hydrated despite the 2-5s random wait; XHS A/B page variants where selectors don't match; risk-control serving a blank shell page; xsec_token expired producing an odd page state.","solutions":["Retry — a not-yet-hydrated page is the most common cause.","Verify the URL renders a real note page in the logged-in browser.","Check for security-block/login pages manually; if present the session needs attention.","Regenerate a fresh URL with a valid xsec_token."],"exampleFix":"// before\nconst data = await page.evaluate(NOTE_EXTRACT_JS); // too early\n// after\nawait page.wait({ time: 4 });\nconst data = await page.evaluate(NOTE_EXTRACT_JS);\nif (!data || typeof data !== 'object') throw new EmptyResultError('xiaohongshu/note', 'Unexpected evaluate response');","handlingStrategy":"retry","validationCode":"// Nothing to pre-validate client-side; ensure the URL is a valid signed note URL first\nif (!/[?&]xsec_token=/.test(raw)) console.warn('URL lacks xsec_token; extraction may fail');","typeGuard":"function isExtractPayload(v) {\n  return !!v && typeof v === 'object' && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  await note(url);\n} catch (err) {\n  if (err instanceof EmptyResultError && err.message.includes('Unexpected evaluate response')) {\n    await sleep(3000);\n    return note(url); // page likely hadn't hydrated\n  } else throw err;\n}","preventionTips":["Retry once with a longer delay before treating the note as unavailable.","Use fresh signed URLs — expired tokens can produce unusable pages.","Run on a stable network so the SPA can hydrate within the wait window."],"tags":["xiaohongshu","page-evaluate","empty-result"],"backgroundTag":"empty-page-extraction-result","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}