mastra-ai/mastra · error · Error
Failed to fetch CDP version info from ${versionUrl}: ${respo
Error message
Failed to fetch CDP version info from ${versionUrl}: ${response.status} ${response.statusText} What it means
When connecting to an external CDP endpoint given as an http(s) URL, the browser queries <host>/json/version to discover the webSocketDebuggerUrl. If the HTTP response is not ok, it throws with the status code and status text. This means the endpoint answered but rejected the request.
Source
Thrown at packages/core/src/browser/browser.ts:929
}
// HTTP URL - fetch /json/version to get the WebSocket URL
if (url.startsWith('http://') || url.startsWith('https://')) {
const baseUrl = url.replace(/\/$/, ''); // Remove trailing slash
const versionUrl = `${baseUrl}/json/version`;
this.logger.debug?.(`Resolving WebSocket URL from ${versionUrl}`);
// Add timeout to prevent hanging on dead endpoints
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000);
try {
const response = await fetch(versionUrl, { signal: controller.signal });
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error(
`Failed to fetch CDP version info from ${versionUrl}: ${response.status} ${response.statusText}`,
);
}
const data = (await response.json()) as { webSocketDebuggerUrl?: string };
if (!data.webSocketDebuggerUrl) {
throw new Error(`No webSocketDebuggerUrl found in CDP version response from ${versionUrl}`);
}
this.logger.debug?.(`Resolved WebSocket URL: ${data.webSocketDebuggerUrl}`);
return data.webSocketDebuggerUrl;
} catch (error) {
clearTimeout(timeoutId);
if (error instanceof Error && error.name === 'AbortError') {
throw new Error(`Timeout resolving WebSocket URL from ${versionUrl} (10s)`);
}
throw error;
}View on GitHub (pinned to 75dd419e61)
Solutions
- Verify Chrome was launched with --remote-debugging-port=<port> and curl the same versionUrl from the app host.
- Fix proxy/ingress rules so /json/version is forwarded and returns 200.
- Use the correct protocol prefix (ws:// / wss:// for direct WebSocket, http(s) only for the version endpoint).
- Check the port isn't claimed by another process.
Example fix
// before
await browser.connectToExternalCdp('https://my-proxy.example.com/chrome'); // 404 on /json/version
// after
await browser.connectToExternalCdp('ws://127.0.0.1:9222/devtools/browser/<id>'); // direct ws URL Defensive patterns
Strategy: fallback
Validate before calling
// probe the version endpoint before attaching
const res = await fetch(versionUrl.replace(/\/$/, '') + '/json/version');
if (!res.ok) throw new Error(`CDP version endpoint unhealthy: ${res.status}`); Type guard
function isCdpVersionOk(d: unknown): d is { webSocketDebuggerUrl: string } {
return typeof d === 'object' && d !== null && 'webSocketDebuggerUrl' in d && typeof (d as any).webSocketDebuggerUrl === 'string';
} Try / catch
try {
await browser.connectToExternalCdp(versionUrl);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Failed to fetch CDP version info')) {
// fall back to constructing the ws URL directly
await browser.connectToExternalCdp(versionUrl.replace(/^http/, 'ws').replace(/\/$/, '') + '/devtools/browser');
} else throw err;
} Prevention
- curl /json/version from the app host before wiring up CDP attach.
- Ensure proxies forward the version endpoint untouched.
- Prefer passing a ws:// URL directly when you already know it.
- Verify the port isn't occupied by a non-Chrome service.
When it happens
Trigger: The CDP URL points at a host/port where /json/version returns 4xx/5xx — e.g. a proxy requiring auth, a DevTools endpoint bound to a different path, a port occupied by a non-Chrome service, or a remote debugging endpoint returning 502/503.
Common situations: Chrome launched without --remote-debugging-port but something else listens on that port; reverse proxy rules not forwarding /json/version; connecting to a containerized Chrome through an ingress that blocks the endpoint; TLS mismatch producing a gateway error.
Related errors
- Failed to fetch CDP version info from ${versionUrl}: ${respo
- No webSocketDebuggerUrl found in CDP version response from $
- Timeout resolving WebSocket URL from ${versionUrl} (10s)
- Slack OAuth HTTP error: ${tokenResponse.status} ${tokenRespo
- Failed to stream background tasks: ${response.statusText}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/9674dd2deef5f673.
Report an issue: GitHub.