{"record":{"id":"a635e1f8ba65a837","repo":"jackwener/OpenCLI","slug":"browser-page-required-a635e1","errorCode":null,"errorMessage":"Browser page required","messagePattern":"Browser page required","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/linux-do/feed.js","lineNumber":70,"sourceCode":"    }\n}\nasync function writeMetadataCache(name, data) {\n    try {\n        const cacheDir = getLinuxDoCacheDir();\n        await fs.promises.mkdir(cacheDir, { recursive: true });\n        const payload = {\n            fetchedAt: new Date().toISOString(),\n            data,\n        };\n        await fs.promises.writeFile(getMetadataCachePath(name), JSON.stringify(payload, null, 2) + '\\n');\n    }\n    catch {\n        // Cache write failures should never block command execution.\n    }\n}\nasync function ensureLinuxDoHome(page) {\n    if (!page)\n        throw new CommandExecutionError('Browser page required');\n    await page.goto(LINUX_DO_HOME);\n    await page.wait(2);\n}\nexport async function fetchLinuxDoJson(page, apiPath, options = {}) {\n    if (!options.skipNavigate) {\n        await ensureLinuxDoHome(page);\n    }\n    if (!page)\n        throw new CommandExecutionError('Browser page required');\n    const escapedPath = JSON.stringify(apiPath);\n    const result = await page.evaluate(`(async () => {\n    try {\n      const res = await fetch(${escapedPath}, { credentials: 'include' });\n      let data = null;\n      try { data = await res.json(); } catch {}\n      return {\n        ok: res.ok,\n        status: res.status,","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linux-do/feed.js#L52-L88","documentation":"ensureLinuxDoHome navigates the automation page to https://linux.do before any feed work, and this CommandExecutionError is thrown when it is called with no page object at all. Every linux.do command in this module runs through a real browser page (site strategy is COOKIE/browser-based), so a null/undefined page is a programming or wiring error, not a site-side failure. It surfaces from both fetchLinuxDoJson and runLinuxDoFeed whenever the browser handle was never created or was not passed down.","triggerScenarios":"Calling fetchLinuxDoJson(page, path) with page === null/undefined (and options.skipNavigate falsy, so ensureLinuxDoHome runs first); calling runLinuxDoFeed/ensureLinuxDoHome directly with no page; a CLI/plugin integration that constructs the command without browser:true or that lost the browser handle before invoking the command.","commonSituations":"Embedding the CLI's internal functions in a script and forgetting to launch the browser/obtain a page; a wrapper that catches browser-launch failure but still calls the feed command; tests or mocks that pass undefined instead of a page stub.","solutions":["Ensure the browser is launched and a page is obtained before invoking any linux-do feed command (the CLI does this automatically when the command declares browser: true — use the CLI rather than internals).","If calling fetchLinuxDoJson yourself, pass the live page object and check it is non-null first.","If you already navigated and want to reuse the page, pass { skipNavigate: true } — but the page argument is still required.","Fix upstream wiring: verify browser launch succeeded and that the page wasn't closed/nulled before the call."],"exampleFix":"// before\nconst data = await fetchLinuxDoJson(null, '/latest.json');\n// after\nconst page = await browser.newPage();\nconst data = await fetchLinuxDoJson(page, '/latest.json');","handlingStrategy":"type-guard","validationCode":"if (!page || typeof page.goto !== 'function') {\n  throw new Error('ensureLinuxDoHome requires an open browser page');\n}","typeGuard":"function isBrowserPage(p) {\n  return !!p && typeof p === 'object' &&\n    typeof p.goto === 'function' && typeof p.evaluate === 'function';\n}","tryCatchPattern":"try {\n  await ensureLinuxDoHome(page);\n} catch (err) {\n  if (/Browser page required/.test(err.message)) {\n    page = await browser.newPage(); // recover by opening the missing page\n    await ensureLinuxDoHome(page);\n    return;\n  }\n  throw err;\n}","preventionTips":["Only invoke linux-do commands through the CLI, which launches the browser and supplies the page automatically.","Guard any direct calls to ensureLinuxDoHome/fetchLinuxDoJson/runLinuxDoFeed with a null-page check.","Don't null out or close the page variable between browser launch and command execution.","Handle browser-launch failures by aborting the command, not by proceeding with an undefined page."],"tags":["linux-do","browser-automation","argument-error","programming-error"],"backgroundTag":"missing-browser-page","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}