Mintplex-Labs/anything-llm · error · Error

No browser pages open.

Error message

No browser pages open.

What it means

Thrown by cdp-eval after successfully connecting to Chromium's browser WS endpoint: Target.getTargets returned targets, but after filtering to type 'page' and excluding chrome:// and devtools:// URLs the list is empty. So the debugger is reachable but there is no attachable web page — only internal chrome pages (new tab, settings, devtools windows) or non-page targets (service workers, background pages) exist.

Solutions

  1. Open a real web page in the Chromium instance (any http/https URL) and retry the eval call
  2. If racing at startup, retry after a short delay once the start page has loaded
  3. Change the browser's startup/home page to a real URL (not chrome://newtab) so a page target always exists
  4. Confirm with curl http://127.0.0.1:9222/json/list that at least one entry has type page and a non-chrome:// url

Example fix

# before: only chrome://newtab open -> 'No browser pages open.'
# after: pre-open a page before running the helper
chromium --remote-debugging-port=9222 --user-data-dir=/tmp/oc-chrome 'https://example.com' &
curl -s http://127.0.0.1:9222/json/list | jq '.[] | select(.type=="page") | .url'
Defensive patterns

Strategy: validation

Validate before calling

async function hasRealPage() {
  const targets = await (await fetch('http://127.0.0.1:9222/json/list')).json();
  return targets.some((t) => t.type === 'page' && !t.url.startsWith('chrome://') && !t.url.startsWith('devtools://'));
}
if (!(await hasRealPage())) { /* open http://example.com in the debugged Chromium first */ }

Try / catch

try { await evalInPage(expr); } catch (e) { if (/No browser pages open/.test(e.message)) { await openPage('https://example.com'); await evalInPage(expr); } else throw e; }

Prevention

When it happens

Trigger: Chromium freshly started with remote debugging but sitting on the NTP (chrome://newtab) with no site opened; all tabs navigated to chrome:// URLs; only DevTools windows are open; the agent opened the browser but a page navigation has not happened yet.

Common situations: Race at session start: the helper runs before the agent's start page (e.g. about:blank vs a real URL) finishes creating; user manually closed all regular tabs while the agent was working; kiosk setups that only ever show chrome://apps.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18). Data as JSON: /api/errors/d4ea5693ba14dea9. Report an issue: GitHub.

Appendix: source

Thrown at open-computer/services/interface-service/utils/cdp-eval.js:85

async function main() {
  const versionRaw = await httpGet("http://127.0.0.1:9222/json/version");
  const version = JSON.parse(versionRaw);
  const browserWsUrl = version.webSocketDebuggerUrl;
  if (!browserWsUrl) throw new Error("No webSocketDebuggerUrl — is Chromium running?");

  const ws = await new Promise((resolve, reject) => {
    const socket = new WebSocket(browserWsUrl);
    const t = setTimeout(() => reject(new Error("WS connect timeout")), 5000);
    socket.on("open", () => { clearTimeout(t); resolve(socket); });
    socket.on("error", (err) => { clearTimeout(t); reject(err); });
  });

  try {
    const { targetInfos } = await cdpSend(ws, "Target.getTargets");
    const pages = targetInfos.filter(
      (t) => t.type === "page" && !t.url.startsWith("chrome://") && !t.url.startsWith("devtools://")
    );
    if (pages.length === 0) throw new Error("No browser pages open.");

    let target = pages[pages.length - 1];
    if (targetUrl) {
      const match = pages.find(
        (p) => p.url.includes(targetUrl) || p.title.toLowerCase().includes(targetUrl.toLowerCase())
      );
      if (!match) {
        const openTabs = pages.map((p) => `- ${p.title} ${p.url}`).join("\n");
        throw new Error(`No browser tab matching "${targetUrl}". Open tabs:\n${openTabs}`);
      }
      if (match) target = match;
    }

    const { sessionId } = await cdpSend(ws, "Target.attachToTarget", {
      targetId: target.targetId,
      flatten: true,
    });

View on GitHub (pinned to 3aec848f28)