jackwener/OpenCLI · error · CommandExecutionError

Browser page required

Error message

Browser page required

What it means

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.

Source

Thrown at clis/linux-do/feed.js:70

    }
}
async function writeMetadataCache(name, data) {
    try {
        const cacheDir = getLinuxDoCacheDir();
        await fs.promises.mkdir(cacheDir, { recursive: true });
        const payload = {
            fetchedAt: new Date().toISOString(),
            data,
        };
        await fs.promises.writeFile(getMetadataCachePath(name), JSON.stringify(payload, null, 2) + '\n');
    }
    catch {
        // Cache write failures should never block command execution.
    }
}
async function ensureLinuxDoHome(page) {
    if (!page)
        throw new CommandExecutionError('Browser page required');
    await page.goto(LINUX_DO_HOME);
    await page.wait(2);
}
export async function fetchLinuxDoJson(page, apiPath, options = {}) {
    if (!options.skipNavigate) {
        await ensureLinuxDoHome(page);
    }
    if (!page)
        throw new CommandExecutionError('Browser page required');
    const escapedPath = JSON.stringify(apiPath);
    const result = await page.evaluate(`(async () => {
    try {
      const res = await fetch(${escapedPath}, { credentials: 'include' });
      let data = null;
      try { data = await res.json(); } catch {}
      return {
        ok: res.ok,
        status: res.status,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. 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).
  2. If calling fetchLinuxDoJson yourself, pass the live page object and check it is non-null first.
  3. If you already navigated and want to reuse the page, pass { skipNavigate: true } — but the page argument is still required.
  4. Fix upstream wiring: verify browser launch succeeded and that the page wasn't closed/nulled before the call.

Example fix

// before
const data = await fetchLinuxDoJson(null, '/latest.json');
// after
const page = await browser.newPage();
const data = await fetchLinuxDoJson(page, '/latest.json');
Defensive patterns

Strategy: type-guard

Validate before calling

if (!page || typeof page.goto !== 'function') {
  throw new Error('ensureLinuxDoHome requires an open browser page');
}

Type guard

function isBrowserPage(p) {
  return !!p && typeof p === 'object' &&
    typeof p.goto === 'function' && typeof p.evaluate === 'function';
}

Try / catch

try {
  await ensureLinuxDoHome(page);
} catch (err) {
  if (/Browser page required/.test(err.message)) {
    page = await browser.newPage(); // recover by opening the missing page
    await ensureLinuxDoHome(page);
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/a635e1f8ba65a837. Report an issue: GitHub.