Mintplex-Labs/anything-llm · error
No browser pages open.
Error message
No browser pages open.
What it means
cdp-input sibling of cdp-eval's page check: after Target.getTargets, pages are filtered to type 'page' excluding chrome:// and devtools:// URLs; if none remain, input injection has no target and the helper aborts with this error. The connection and WS handshake succeeded — the browser simply exposes no regular web page to attach to.
Solutions
- Navigate to or open a real http/https page, then retry the input command
- Add a small retry/delay right after browser launch until /json/list shows a page-type target with a non-chrome:// URL
- Set the agent's launch URL to a real page so a valid target always exists at startup
- Reopen crashed tabs (chrome://restore is filtered too — navigate explicitly) before injecting input
Example fix
# before chromium --remote-debugging-port=9222 --user-data-dir=/tmp/oc-chrome & node cdp-input.js click 100 200 # NTP only -> error # after: launch straight into a page chromium --remote-debugging-port=9222 --user-data-dir=/tmp/oc-chrome https://example.com & node cdp-input.js click 100 200
Defensive patterns
Strategy: validation
Validate before calling
async function hasAttachablePage() {
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://'));
} Try / catch
try { await sendInput('click', x, y); } catch (e) { if (/No browser pages open/.test(e.message)) { await openPage('https://example.com'); await sendInput('click', x, y); } else throw e; } Prevention
- Start Chromium with an http(s) URL argument so the NTP filter never empties the page list
- Retry once after a short delay at startup — page targets appear asynchronously after launch
- Guard scripts that close tabs so the last regular page is never closed
When it happens
Trigger: Attempting click/type/key immediately after launching Chromium whose only tab is the new-tab page; the user (or page JS) closed all regular tabs; every open tab is a chrome:// internal page.
Common situations: Startup race where input is dispatched before the agent's start page finishes opening; kiosk/new-profile Chromium instances sitting on NTP; sessions where the page crashed and Chrome shows the sad-tab chrome://crash page.
Related errors
- No browser pages open.
- No webSocketDebuggerUrl — is Chromium running?
- click requires coordinates
- key requires argument (e.g. Enter, Tab, Escape)
- No browser tab matching
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/a460604ffbf9305c.
Report an issue: GitHub.
Appendix: source
Thrown at open-computer/services/interface-service/utils/cdp-input.js:92
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 {
// Find target page
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.");
// Determine target URL filter (always last arg if it doesn't look like a coordinate/text)
let targetUrl = "";
if (action === "click") {
targetUrl = process.argv[5] || "";
} else if (action === "type") {
targetUrl = process.argv[4] || "";
} else if (action === "key") {
targetUrl = process.argv[4] || "";
}
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");View on GitHub (pinned to 3aec848f28)