can1357/oh-my-pi · error · ToolError

autoStarted ? `omp browser relay is serving at ${cdpUrl} but

Error message

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.`

What it means

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.

Source

Thrown at packages/coding-agent/src/tools/browser/registry.ts:234

	if (kind.kind === "relay") {
		const cdpUrl = normalizeConnectedCdpUrl(kind.cdpUrl);
		// Loopback relays are owned by a machine-global broker and auto-started
		// on demand (the extension dials in on its own). Hosts without a CLI
		// worker entry (bun test, SDK embedding) never spawn brokers. Remote
		// relay URLs must already be serving.
		let autoStarted = false;
		if (isLoopbackRelayUrl(cdpUrl) && (isCompiledBinary() || workerHostEntry() !== null)) {
			autoStarted = await ensureRelayDaemon({ cdpUrl, signal: opts.signal });
		}
		// The relay answers /json/version with 503 until its extension dials in.
		// A freshly revived extension service worker can take up to ~30s (its
		// keepalive alarm) to reconnect, so give the handshake that long.
		try {
			await waitForCdp(cdpUrl, RELAY_EXTENSION_WAIT_MS, opts.signal);
		} catch (err) {
			if (err instanceof ToolAbortError) throw err;
			if (err instanceof Error && err.name === "AbortError") throw err;
			throw new ToolError(
				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.`,
			);
		}
		const puppeteer = await loadPuppeteer();
		const browser = await puppeteer.connect({
			browserURL: cdpUrl,
			defaultViewport: null,
			protocolTimeout: BROWSER_PROTOCOL_TIMEOUT_MS,
		});
		return {
			key: browserKey(kind),
			kind,
			browser,
			cdpUrl,
			refCount: 0,
			stealth: { browserSession: null, override: null },

View on GitHub (pinned to 9690622007)

Solutions

  1. Run `omp browser-relay install` to install the extension and confirm the toolbar badge shows "on"
  2. Start the relay manually with `omp browser-relay` and verify the endpoint (cdpUrl) is reachable, e.g. curl http://<cdpUrl>/json/version
  3. Ensure Chrome is running with the OMP Browser Relay extension loaded
  4. Check ~/.omp/logs for relay startup errors if the relay fails to stay up

Example fix

// before (shell)
omp browser open --kind relay
// after (shell)
omp browser-relay install   # one-time: load the extension
omp browser-relay &         # ensure the relay is serving
omp browser open --kind relay
Defensive patterns

Strategy: validation

Validate before calling

// before opening a relay browser, check the relay endpoint is live
const res = await fetch(`${cdpUrl}/json/version`).catch(() => null);
if (!res?.ok) {
  console.error(`Relay not reachable at ${cdpUrl}; run: omp browser-relay`);
}

Try / catch

try {
  await openRelayBrowser({ signal });
} catch (err) {
  if (err instanceof ToolError && err.message.includes("browser relay")) {
    // guide user: install extension / start relay
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/22be8aefc36c66e3. Report an issue: GitHub.