{"record":{"id":"d389d571acd4368b","repo":"jackwener/OpenCLI","slug":"webhost-feed-unexpected-evaluate-response","errorCode":null,"errorMessage":"${webHost} feed: unexpected evaluate response","messagePattern":"(.+?) feed: unexpected evaluate response","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/feed.js","lineNumber":105,"sourceCode":"        return url.toString();\n    url.searchParams.set('xsec_token', cleanToken);\n    url.searchParams.set('xsec_source', '');\n    return url.toString();\n}\n\n/**\n * Shared func-mode implementation. Exported so the rednote adapter can run the\n * same store read against www.rednote.com without duplicating the logic.\n */\nexport async function runFeed(page, kwargs, webHost) {\n    const limit = parseLimit(kwargs.limit);\n    await page.goto(`https://${webHost}/explore`);\n    // Pinia store hydrates from SSR; give the page a beat to finish\n    // bootstrapping before reading the array.\n    await page.wait({ time: 2 });\n    const data = unwrapEvaluateResult(await page.evaluate(FEEDS_READ_JS));\n    if (!data || typeof data !== 'object') {\n        throw new CommandExecutionError(`${webHost} feed: unexpected evaluate response`);\n    }\n    if (data.error) {\n        throw new CommandExecutionError(`${webHost} feed: ${data.error}`, `The SPA may still be hydrating; reload ${webHost}/explore and retry.`);\n    }\n    if (!Array.isArray(data.items)) {\n        throw new CommandExecutionError(`${webHost} feed: unexpected items payload shape`);\n    }\n    const rows = [];\n    for (const row of data.items) {\n        if (rows.length >= limit)\n            break;\n        if (!row || typeof row !== 'object') {\n            throw new CommandExecutionError(`${webHost} feed: malformed feed item`);\n        }\n        const id = toCleanString(row.id);\n        if (!id) {\n            throw new CommandExecutionError(`${webHost} feed: feed item is missing note id`);\n        }","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/feed.js#L87-L123","documentation":"runFeed evaluates FEEDS_READ_JS in the page and requires the result to be a non-null object. If unwrapEvaluateResult returns null/primitive, it throws CommandExecutionError 'unexpected evaluate response'. This guards against the in-page script failing to return the expected hydration object.","triggerScenarios":"page.evaluate(FEEDS_READ_JS) resolves to undefined/null or a non-object after page.goto(https://<webHost>/explore) and a 2-second wait.","commonSituations":"The SPA failed to boot (JS error on page), redirect to a login/captcha page where the expected global store does not exist, network issues leaving /explore blank, or site changes removing the store the script reads.","solutions":["Reload https://<webHost>/explore and retry after the page fully renders","Verify you are logged in and not redirected to a login or captcha page","Increase the wait time after goto before evaluating (SPA may need longer than 2s)","Open DevTools on /explore and run the same script to see what the store returns","Check for site updates that changed the Pinia store structure and update FEEDS_READ_JS"],"exampleFix":"// before\nawait page.wait({ time: 2 });\nconst data = unwrapEvaluateResult(await page.evaluate(FEEDS_READ_JS));\n// after\nawait page.wait({ time: 5 }); // longer hydration window\nawait page.waitForSelector('.note-item'); // ensure feed rendered\nconst data = unwrapEvaluateResult(await page.evaluate(FEEDS_READ_JS));","handlingStrategy":"retry","validationCode":"// ensure page is on explore and rendered before evaluating\nif (!page.url().includes('/explore')) await page.goto(`https://${webHost}/explore`);\nawait page.waitForSelector('.note-item');","typeGuard":"function isFeedPayload(d) { return !!d && typeof d === 'object'; }","tryCatchPattern":"try {\n  const data = unwrapEvaluateResult(await page.evaluate(FEEDS_READ_JS));\n} catch (err) {\n  if (err instanceof CommandExecutionError && err.message.includes('unexpected evaluate response')) {\n    await page.reload(); await page.wait({ time: 5 }); // retry once\n  } else throw err;\n}","preventionTips":["Wait for feed DOM selectors instead of fixed sleeps","Confirm login state before navigating to /explore","Handle login/captcha redirects explicitly","Re-verify FEEDS_READ_JS against the current site store after site updates"],"tags":["browser-automation","spa","feed"],"backgroundTag":"browser-evaluate-unexpected-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}