can1357/oh-my-pi · error · ToolError
Browser websocket endpoint is unavailable
Error message
Browser websocket endpoint is unavailable
What it means
buildInitPayload reads the Puppeteer browser's WebSocket endpoint (browser.wsEndpoint()) to hand it to the tab worker. If the endpoint is absent the browser was not launched with a WS listener (or is already disconnected), so the worker cannot attach and a ToolError is thrown.
Source
Thrown at packages/coding-agent/src/tools/browser/tab-supervisor.ts:772
if (await releaseTab(name, opts)) count++;
}
return count;
}
/** Test-only accessor for the module-global tabs map. */
export function getTabsMapForTest(): ReadonlyMap<string, TabSession> {
return tabs;
}
function isLastSurfaceCloseError(err: unknown): boolean {
const message = err instanceof Error ? err.message : String(err);
return /last/i.test(message);
}
async function buildInitPayload(browser: PuppeteerBrowserHandle, opts: AcquireTabOptions): Promise<WorkerInitPayload> {
const safeDir = getPuppeteerDir();
const browserWSEndpoint = browser.browser.wsEndpoint();
if (!browserWSEndpoint) throw new ToolError("Browser websocket endpoint is unavailable");
if (browser.kind.kind === "headless") {
return {
mode: "headless",
browserWSEndpoint,
safeDir,
// Visible launches still need an OMP-owned page, stealth setup, and
// independent lifecycle; only their fixed device emulation is disabled.
emulateViewport: browser.kind.headless,
viewport: opts.viewport,
dialogs: opts.dialogs,
url: opts.url,
waitUntil: opts.waitUntil,
timeoutMs: opts.timeoutMs,
};
}
// Connected and relay browsers are user-driven. When no target is requested,
// adopt the visible tab and avoid raising it before screenshots. An explicit
// target may be backgrounded, so retain activation for target-correct pixels.View on GitHub (pinned to 9690622007)
Solutions
- Verify the browser process is running and was launched with a WS endpoint; close and relaunch the browser.
- Re-open the tab — a fresh acquire will relaunch a healthy browser if the old one died.
- Check system resources/logs for Chrome startup crashes (OOM, missing sandbox flags).
- Ensure nothing in the environment forces pipe transport or disables the DevTools WS listener.
Example fix
// before
const stale = getBrowserHandle(); // process died
await openTab(stale); // wsEndpoint() empty
// after
await closeBrowser(stale, { kill: true });
const tab = await openTab({ name: "docs", url }); // relaunches browser with WS endpoint Defensive patterns
Strategy: try-catch
Validate before calling
const ep = handle.browser.wsEndpoint();
if (!ep || !handle.browser.connected) {
await relaunchBrowser();
} Type guard
function hasWsEndpoint(b: { wsEndpoint(): string | undefined; connected: boolean }): boolean {
return b.connected && typeof b.wsEndpoint() === "string" && b.wsEndpoint().length > 0;
} Try / catch
try {
await openTab(handle);
} catch (e) {
if (e instanceof ToolError && e.message === "Browser websocket endpoint is unavailable") {
await closeBrowser(handle, { kill: true });
return openTab(freshHandle()); // relaunch
}
throw e;
} Prevention
- Launch the browser with a WS (DevTools) listener, not pipe-only transport
- Check browser.connected before reuse of long-lived handles
- Monitor for Chrome startup crashes (OOM, missing flags) in logs
When it happens
Trigger: Browser handle launched without a websocket endpoint (e.g. launched with pipe transport), the browser process exited/died before the worker attached, or the handle references a disconnected browser instance.
Common situations: Browser crashed between launch and worker spawn; browser launched with browserWSEndpoint disabled / pipe mode; reusing a stale handle after the process was killed; resource limits (OOM) killing Chrome at startup.
Related errors
- Shared browser attach failed: ${err instanceof Error ? err.m
- Connected to ${cdpUrl} but puppeteer.connect failed: ${(err
- Target ${payload.targetId} is no longer available on the att
- Target ${targetId} is no longer available on the attached br
- Sealed frame too short
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/9f8f12165b655b16.
Report an issue: GitHub.