diegosouzapw/OmniRoute · error · Error

No CDP websocket endpoint from browser container

Error message

No CDP websocket endpoint from browser container

What it means

Thrown by harvestFromContainer when the browser container's CDP /json/version endpoint responds but its JSON lacks a usable webSocketDebuggerUrl (missing, non-string, or empty). Means the Chromium instance inside the VNC container is not exposing a debug websocket — typically a container image mismatch or a browser that started without the remote-debugging flags, not a network failure (the HTTP fetch itself succeeded).

Solutions

  1. Verify the container is running the expected omniroute-vnc-chromium image with remote debugging enabled on the CDP port
  2. Curl http://127.0.0.1:<cdpPort>/json/version manually and confirm webSocketDebuggerUrl is present and non-empty
  3. Rebuild/restart the browser container if the browser process launched without --remote-debugging-port
  4. Treat as a session-level failure: mark the session error and let the user restart browser login
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/lib/vncSession/harvest.ts:293 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of diegosouzapw/OmniRoute@a179ffed5b (2026-08-25). Data as JSON: /api/errors/252baa17fd2403ad. Report an issue: GitHub.

Appendix: source

Thrown at src/lib/vncSession/harvest.ts:293

}

export async function harvestFromContainer(
  cdpPort: number,
  provider: VncProviderEntry,
  timeoutMs = 20_000
): Promise<HarvestResult> {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
  let client: CdpClient | null = null;

  try {
    const version = await fetchJson(
      `http://127.0.0.1:${cdpPort}/json/version`,
      controller.signal
    );
    const debuggerUrl = version?.webSocketDebuggerUrl;
    if (typeof debuggerUrl !== "string" || !debuggerUrl) {
      throw new Error("No CDP websocket endpoint from browser container");
    }

    client = new CdpClient(rewriteDebuggerUrl(debuggerUrl, cdpPort));
    await client.ready(Math.min(timeoutMs, 15_000), controller.signal);

    const origin = new URL(provider.url).origin;
    await client.attachToPage(origin, controller.signal);
    const [cookiesRaw, declaredStorage] = await Promise.all([
      client.getCookies(provider.url, controller.signal),
      client.getDeclaredStorage(provider.requirement.storageKeys, controller.signal),
    ]);

    const cookies = cookiesRaw
      .filter((cookie: any) => domainMatches(cookie.domain, origin))
      .map((cookie: any) => ({
        name: String(cookie.name || ""),
        value: String(cookie.value || ""),
        domain: String(cookie.domain || ""),

View on GitHub (pinned to a179ffed5b)