{"record":{"id":"9f4562e7c231993a","repo":"jackwener/OpenCLI","slug":"qoder-read","errorCode":null,"errorMessage":"qoder read","messagePattern":"qoder read","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"error","filePath":"clis/qoder/read.js","lineNumber":21,"sourceCode":"import { evaluateQoder, parsePositiveInt, QODER_TURNS_JS, requireArrayResult } from './_utils.js';\n\ncli({\n    site: 'qoder',\n    name: 'read',\n    access: 'read',\n    description: 'Read messages in the current Qoder Quest. Returns role + text for each visible turn.',\n    domain: 'localhost',\n    strategy: Strategy.UI,\n    browser: true,\n    args: [\n        { name: 'limit', type: 'int', required: false, default: 30 },\n    ],\n    columns: ['Index', 'Role', 'Text'],\n    func: async (page, kwargs) => {\n        const limit = parsePositiveInt(kwargs?.limit, 30, '--limit');\n        const turns = requireArrayResult(await evaluateQoder(page, QODER_TURNS_JS), 'qoder read');\n        if (!turns.length) {\n            throw new EmptyResultError('qoder read', 'No chat turns detected. Open a quest first.');\n        }\n        return turns.slice(0, limit).map((t, i) => ({\n            Index: i + 1,\n            Role: t.role,\n            Text: (t.text || '').slice(0, 1200),\n        }));\n    },\n});\n","sourceCodeStart":3,"sourceCodeEnd":30,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/qoder/read.js#L3-L30","documentation":"Thrown when the qoder read command's DOM-extraction script (QODER_TURNS_JS) fails to return an array, meaning the chat turn scrape did not produce usable data. The library guards with requireArrayResult to fail fast instead of returning garbage. Unlike EmptyResultError, this indicates the extraction script itself broke rather than an empty chat.","triggerScenarios":"Qoder's chat DOM changed so QODER_TURNS_JS returns null/undefined or a non-array; evaluateQoder threw or returned an error object; the page is not on a quest/chat view (no message list mounted).","commonSituations":"Qoder frontend update renaming message-list containers; running qoder read before opening any quest so the turn container doesn't exist; a stale logged-out page where the chat never renders.","solutions":["Open a quest/chat in Qoder first so the turn list exists, then rerun.","Reload the quest page and retry.","Inspect the current DOM and update QODER_TURNS_JS selectors to match the new markup.","Check that you are logged in and the page is fully loaded before running the command."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"const onQuest = await page.evaluate(`!!document.querySelector('[class*=\"message\"], [class*=\"chat\"]')`);\nif (!onQuest) throw new Error('Open a quest page before running qoder read');","typeGuard":"function isTurnArray(v) { return Array.isArray(v) && v.every(t => t && typeof t.text === 'string'); }","tryCatchPattern":"try {\n  const turns = await read(page);\n} catch (e) {\n  if (/qoder read/.test(String(e.message))) {\n    await page.reload();\n    return read(page);\n  }\n  throw e;\n}","preventionTips":["Always open/verify a quest before calling read.","Reload the page after Qoder updates to avoid stale DOM.","Treat EmptyResultError (empty chat) and this array failure differently when handling.","Re-verify QODER_TURNS_JS selectors whenever the Qoder frontend updates."],"tags":["dom-extraction","scraping","invalid-result"],"backgroundTag":"dom-scrape-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}