{"record":{"id":"22be8aefc36c66e3","repo":"can1357/oh-my-pi","slug":"autostarted-omp-browser-relay-is-serving-at-c","errorCode":null,"errorMessage":"autoStarted ? `omp browser relay is serving at ${cdpUrl} but its extension never connected. Install it with \\`omp browser-relay install\\` and check the toolbar badge shows \"on\".` : `omp browser relay is not reachable at ${cdpUrl}. Start it with \\`omp browser-relay\\` (or check the endpoint), and make sure the OMP Browser Relay extension is loaded in Chrome.`","messagePattern":"autoStarted \\? `omp browser relay is serving at (.+?) but its extension never connected\\. Install it with \\\\`omp browser-relay install\\\\` and check the toolbar badge shows \"on\"\\.` : `omp browser relay is not reachable at (.+?)\\. Start it with \\\\`omp browser-relay\\\\` \\(or check the endpoint\\), and make sure the OMP Browser Relay extension is loaded in Chrome\\.`","errorType":"exception","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/browser/registry.ts","lineNumber":234,"sourceCode":"\tif (kind.kind === \"relay\") {\n\t\tconst cdpUrl = normalizeConnectedCdpUrl(kind.cdpUrl);\n\t\t// Loopback relays are owned by a machine-global broker and auto-started\n\t\t// on demand (the extension dials in on its own). Hosts without a CLI\n\t\t// worker entry (bun test, SDK embedding) never spawn brokers. Remote\n\t\t// relay URLs must already be serving.\n\t\tlet autoStarted = false;\n\t\tif (isLoopbackRelayUrl(cdpUrl) && (isCompiledBinary() || workerHostEntry() !== null)) {\n\t\t\tautoStarted = await ensureRelayDaemon({ cdpUrl, signal: opts.signal });\n\t\t}\n\t\t// The relay answers /json/version with 503 until its extension dials in.\n\t\t// A freshly revived extension service worker can take up to ~30s (its\n\t\t// keepalive alarm) to reconnect, so give the handshake that long.\n\t\ttry {\n\t\t\tawait waitForCdp(cdpUrl, RELAY_EXTENSION_WAIT_MS, opts.signal);\n\t\t} catch (err) {\n\t\t\tif (err instanceof ToolAbortError) throw err;\n\t\t\tif (err instanceof Error && err.name === \"AbortError\") throw err;\n\t\t\tthrow new ToolError(\n\t\t\t\tautoStarted\n\t\t\t\t\t? `omp browser relay is serving at ${cdpUrl} but its extension never connected. Install it with \\`omp browser-relay install\\` and check the toolbar badge shows \"on\".`\n\t\t\t\t\t: `omp browser relay is not reachable at ${cdpUrl}. Start it with \\`omp browser-relay\\` (or check the endpoint), and make sure the OMP Browser Relay extension is loaded in Chrome.`,\n\t\t\t);\n\t\t}\n\t\tconst puppeteer = await loadPuppeteer();\n\t\tconst browser = await puppeteer.connect({\n\t\t\tbrowserURL: cdpUrl,\n\t\t\tdefaultViewport: null,\n\t\t\tprotocolTimeout: BROWSER_PROTOCOL_TIMEOUT_MS,\n\t\t});\n\t\treturn {\n\t\t\tkey: browserKey(kind),\n\t\t\tkind,\n\t\t\tbrowser,\n\t\t\tcdpUrl,\n\t\t\trefCount: 0,\n\t\t\tstealth: { browserSession: null, override: null },","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/browser/registry.ts#L216-L252","documentation":"openBrowserHandle, when attaching to the omp browser relay, waits for the relay's CDP endpoint to become live and for the Chrome extension to complete its handshake (waitForCdp). If the endpoint never answers within RELAY_EXTENSION_WAIT_MS, it throws ToolError with a message tailored to whether omp auto-started the relay: either the extension never connected to a running relay, or the relay itself is unreachable.","triggerScenarios":"Calling the browser tool with a relay-based browser kind when (a) the relay was auto-started but the OMP Browser Relay extension never connected, or (b) the relay was expected to already be running at cdpUrl but nothing is listening there, or (c) Chrome is running without the extension loaded.","commonSituations":"Fresh machine where the extension was never installed; Chrome started without the unpacked extension; relay process crashed or was killed after auto-start; wrong port/firewall blocking the relay endpoint; Chrome not running at all.","solutions":["Run `omp browser-relay install` to install the extension and confirm the toolbar badge shows \"on\"","Start the relay manually with `omp browser-relay` and verify the endpoint (cdpUrl) is reachable, e.g. curl http://<cdpUrl>/json/version","Ensure Chrome is running with the OMP Browser Relay extension loaded","Check ~/.omp/logs for relay startup errors if the relay fails to stay up"],"exampleFix":"// before (shell)\nomp browser open --kind relay\n// after (shell)\nomp browser-relay install   # one-time: load the extension\nomp browser-relay &         # ensure the relay is serving\nomp browser open --kind relay","handlingStrategy":"validation","validationCode":"// before opening a relay browser, check the relay endpoint is live\nconst res = await fetch(`${cdpUrl}/json/version`).catch(() => null);\nif (!res?.ok) {\n  console.error(`Relay not reachable at ${cdpUrl}; run: omp browser-relay`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await openRelayBrowser({ signal });\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"browser relay\")) {\n    // guide user: install extension / start relay\n  }\n  throw err;\n}","preventionTips":["Run `omp browser-relay install` once per machine and verify the toolbar badge shows \"on\"","Keep the relay process running (launch at login or via a service) before browser tool calls","Confirm Chrome is running with the OMP Browser Relay extension loaded before opening relay browsers","Health-check the endpoint (GET /json/version) as a preflight in automation"],"tags":["browser","relay","extension","timeout","cdp"],"backgroundTag":"cdp-endpoint-unreachable","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}