jackwener/OpenCLI · error · CommandExecutionError

linux.do returned an empty browser response

Error message

linux.do returned an empty browser response

What it means

fetchLinuxDoJson runs its HTTP request inside the browser page via page.evaluate and expects the async IIFE to resolve to a result object ({ok, status, data, error} or {ok:false, error}). This CommandExecutionError is thrown when evaluate resolves to null/undefined — the page returned nothing to inspect. The library treats an empty response as a command-execution failure because it cannot distinguish success from any error class (auth, HTTP, JSON) without the result envelope.

Source

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

    try {
      const res = await fetch(${escapedPath}, { credentials: 'include' });
      let data = null;
      try { data = await res.json(); } catch {}
      return {
        ok: res.ok,
        status: res.status,
        data,
        error: data === null ? 'Response is not valid JSON' : '',
      };
    } catch (error) {
      return {
        ok: false,
        error: error instanceof Error ? error.message : String(error),
      };
    }
  })()`);
    if (!result) {
        throw new CommandExecutionError('linux.do returned an empty browser response');
    }
    if (result.status === 401 || result.status === 403) {
        throw new AuthRequiredError('linux.do', 'linux.do requires an active signed-in browser session');
    }
    if (!result.ok) {
        throw new CommandExecutionError(result.error || `linux.do request failed: HTTP ${result.status ?? 'unknown'}`);
    }
    if (result.error) {
        throw new CommandExecutionError(result.error, 'Please verify your linux.do session is still valid');
    }
    return result.data;
}
function findMatchingTag(records, value) {
    const raw = value.trim();
    const normalized = normalizeLookupValue(value);
    return /^\d+$/.test(raw)
        ? records.find((item) => item.id === Number(raw)) ?? null
        : records.find((item) => normalizeLookupValue(item.name) === normalized)

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the command — this is often transient (a navigation or hiccup during evaluate). The CLI metadata cache may serve stale-but-valid tags/categories on retry.
  2. Ensure nothing navigates or closes the page during the evaluate; call fetchLinuxDoJson with skipNavigate: true after navigation has settled (networkidle).
  3. Reopen a fresh page to https://linux.do and rerun if the page context may have been destroyed.
  4. If it reproduces every time, check browser/driver versions for evaluate serialization bugs and update the automation runtime.

Example fix

// before
await page.goto('https://linux.do');
const data = await fetchLinuxDoJson(page, '/latest.json'); // page navigated concurrently -> null result
// after
await page.goto('https://linux.do');
await page.waitForLoadState('networkidle');
const data = await fetchLinuxDoJson(page, '/latest.json', { skipNavigate: true });
Defensive patterns

Strategy: retry

Validate before calling

if (!page || (typeof page.isClosed === 'function' && page.isClosed())) {
  throw new Error('Page is gone — reopen it before fetching linux.do JSON');
}

Type guard

function hasResultEnvelope(r) {
  return !!r && typeof r === 'object' && typeof r.ok === 'boolean' &&
    ('status' in r || 'error' in r);
}

Try / catch

try {
  const data = await fetchLinuxDoJson(page, path, { skipNavigate: true });
} catch (err) {
  if (/empty browser response/.test(err.message)) {
    // transient context loss — reopen page, settle navigation, retry once
    page = await browser.newPage();
    await page.goto('https://linux.do');
    await page.waitForLoadState('networkidle');
    return fetchLinuxDoJson(page, path, { skipNavigate: true });
  }
  if (err instanceof AuthRequiredError) return promptLogin();
  throw err;
}

Prevention

When it happens

Trigger: The page context was destroyed mid-evaluate (tab closed, navigation, browser crash) so evaluate resolves null/undefined; the automation driver's evaluate fails to serialize the return value; calling with a page from a different origin/frame where the IIFE is blocked; intermittent driver bug where the evaluated promise is cancelled.

Common situations: linux.do redirects or the user closes the automation window while feed data is loading; browser crashes under memory pressure during large metadata fan-out (categories.json subcategory loop); stale page object reused after browser restart; driver/CDP version incompatibilities swallowing the evaluate result.

Related errors


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