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
- Open a real web page in the Chromium instance (any http/https URL) and retry the eval call
- If racing at startup, retry after a short delay once the start page has loaded
- Change the browser's startup/home page to a real URL (not chrome://newtab) so a page target always exists
- 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
- Launch Chromium with a real start URL so a page target always exists before helpers run
- After browser start, wait until /json/list shows a non-chrome:// page before dispatching eval/input
- Keep at least one regular tab open in automated sessions — don't let scripts close the last one
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
- No browser pages open.
- No browser tab matching
- No webSocketDebuggerUrl — is Chromium running?
- click requires coordinates
- key requires argument (e.g. Enter, Tab, Escape)
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)