{"record":{"id":"699a514f0c582bb2","repo":"jackwener/OpenCLI","slug":"no-rows-returned-from-page-evaluator-page-structu","errorCode":null,"errorMessage":"No rows returned from page evaluator (page structure may have changed)","messagePattern":"No rows returned from page evaluator \\(page structure may have changed\\)","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"error","filePath":"clis/xiaoe/content.js","lineNumber":143,"sourceCode":"})()\n`;\n}\n\nasync function getXiaoeContent(page, args) {\n    const url = requireXiaoePageUrl(args.url, 'content');\n    let rows;\n    try {\n        await page.goto(url, { waitUntil: 'load', settleMs: 6000 });\n        rows = await page.evaluate(buildContentScript());\n    } catch (error) {\n        const message = error instanceof Error ? error.message : String(error);\n        throw new CommandExecutionError(\n            `Failed to extract xiaoe content: ${message}`,\n            'page may not have rendered or auth may be required',\n        );\n    }\n    if (!Array.isArray(rows) || rows.length === 0) {\n        throw new EmptyResultError(\n            'xiaoe/content',\n            'No rows returned from page evaluator (page structure may have changed)',\n        );\n    }\n    const row = rows[0];\n    if (!row || typeof row.content !== 'string' || row.content.length === 0) {\n        throw new EmptyResultError(\n            'xiaoe/content',\n            'No article content extracted — login session may have expired or the page renders an empty shell',\n        );\n    }\n    return rows;\n}\n\nexport const contentCommand = cli({\n    site: 'xiaoe',\n    name: 'content',\n    access: 'read',","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaoe/content.js#L125-L161","documentation":"After the page evaluates successfully, the library expects an array of rows. If the in-page evaluator returns an empty array or something that is not an array, this EmptyResultError is thrown for command xiaoe/content, indicating the page's structure may have changed so the extraction selectors no longer match.","triggerScenarios":"page.evaluate(buildContentScript()) resolves to [] or a non-array (undefined/null), typically because none of CONTENT_SELECTORS matched and the fallbacks produced nothing the script deemed valid.","commonSituations":"Xiaoe shipped a front-end redesign changing .rich-text-wrap and friends; page rendered a bot-check or error state instead of the article; JS-rendered content not ready when the evaluator ran.","solutions":["Retry once in case the page was mid-render","Verify manually in a browser that the URL still shows article content","Update CONTENT_SELECTORS in clis/xiaoe/content.js to match the new DOM structure","Check for a login/bot wall in the rendered page and refresh auth"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  const rows = await getXiaoeContent(url);\n} catch (e) {\n  if (e.name === 'EmptyResultError' && /page structure may have changed/.test(e.message)) {\n    await sleep(3000);\n    return getXiaoeContent(url); // one retry; if it persists, DOM changed\n  }\n  throw e;\n}","preventionTips":["Pin alerting on upstream xiaoe front-end deploys that change DOM classes","Check the page manually in a browser when this error persists across retries","Keep CONTENT_SELECTORS updated when the site redesigns","Distinguish this (structural) from the empty-content auth error before choosing a fix"],"tags":["empty-result","dom-selector","page-structure","xiaoe"],"backgroundTag":"page-extraction-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}