{"record":{"id":"b8680a19e041fc70","repo":"mastra-ai/mastra","slug":"timeout-resolving-websocket-url-from-versionurl-b8680a","errorCode":null,"errorMessage":"Timeout resolving WebSocket URL from ${versionUrl} (10s)","messagePattern":"Timeout resolving WebSocket URL from (.+?) \\(10s\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/browser/browser.ts","lineNumber":944,"sourceCode":"        clearTimeout(timeoutId);\n\n        if (!response.ok) {\n          throw new Error(\n            `Failed to fetch CDP version info from ${versionUrl}: ${response.status} ${response.statusText}`,\n          );\n        }\n\n        const data = (await response.json()) as { webSocketDebuggerUrl?: string };\n        if (!data.webSocketDebuggerUrl) {\n          throw new Error(`No webSocketDebuggerUrl found in CDP version response from ${versionUrl}`);\n        }\n\n        this.logger.debug?.(`Resolved WebSocket URL: ${data.webSocketDebuggerUrl}`);\n        return data.webSocketDebuggerUrl;\n      } catch (error) {\n        clearTimeout(timeoutId);\n        if (error instanceof Error && error.name === 'AbortError') {\n          throw new Error(`Timeout resolving WebSocket URL from ${versionUrl} (10s)`);\n        }\n        throw error;\n      }\n    }\n\n    // Unknown protocol - return as-is and let the caller handle it\n    return url;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Disconnection Detection & Error Handling\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Error patterns that indicate browser disconnection.\n   * Used by isDisconnectionError() to detect external browser closure.\n   */\n  protected static readonly DISCONNECTION_PATTERNS = [","sourceCodeStart":926,"sourceCodeEnd":962,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/browser/browser.ts#L926-L962","documentation":"resolveWebSocketUrl enforces a hard 10-second timeout (AbortController) on the /json/version HTTP fetch. If the request aborts, the AbortError is converted into this descriptive timeout error. It means the CDP endpoint did not answer in time.","triggerScenarios":"The http(s) CDP version URL is unreachable — wrong host/port, firewall dropping packets, Chrome not yet listening, DNS black-holing, or an overloaded endpoint — and fetch hangs until the 10s AbortController fires.","commonSituations":"Connecting before a containerized Chrome finished starting; pointing at a firewalled remote host where packets are silently dropped (hang instead of refuse); typos in hostnames causing long DNS timeouts.","solutions":["Confirm the endpoint responds with curl <versionUrl> before connecting.","Ensure Chrome is fully started (wait for the port to accept connections) before connecting.","Fix network/firewall rules so the host:port is reachable from the app.","Retry with backoff after startup if the browser may still be booting."],"exampleFix":"// before\nawait browser.connectToExternalCdp('http://chrome.internal:9222'); // chrome still starting\n// after\nawait waitUntil(() => fetch('http://chrome.internal:9222/json/version').then(r => r.ok), { retries: 10, delayMs: 500 });\nawait browser.connectToExternalCdp('http://chrome.internal:9222');","handlingStrategy":"retry","validationCode":"const port = new URL('http://host:9222').port;\nawait new Promise<void>((ok, fail) => {\n  const s = net.createConnection({ host: 'host', port: +port });\n  s.on('connect', () => { s.end(); ok(); });\n  s.on('error', fail);\n  s.setTimeout(3000, () => { s.destroy(); fail(new Error('CDP port not reachable')); });\n});","typeGuard":null,"tryCatchPattern":"for (let i = 0; i < 5; i++) {\n  try { await browser.connectToExternalCdp(url); break; }\n  catch (err) {\n    if (err instanceof Error && err.message.startsWith('Timeout resolving WebSocket URL') && i < 4) {\n      await new Promise(r => setTimeout(r, 2000)); // Chrome may still be starting\n      continue;\n    }\n    throw err;\n  }\n}","preventionTips":["Wait for the debug port to accept TCP connections before attaching.","Check firewall/security-group rules for the CDP port.","Verify DNS resolution from the app container, not your laptop.","Add readiness probes on containerized Chrome instances."],"tags":["cdp","timeout","network"],"backgroundTag":"connection-timeout","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}