mastra-ai/mastra · 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
resolveCdpWebSocketUrl fetches the Chrome DevTools Protocol /json/version endpoint to discover the browser's webSocketDebuggerUrl. If the HTTP response is not OK (non-2xx), the library throws with the target URL and status/statusText. This means the CDP endpoint was reachable enough to answer but rejected the request or reported an error.
Source
Thrown at browser/firecrawl/src/resolve-cdp.ts:25
): Promise<string> {
if (url.startsWith('ws://') || url.startsWith('wss://')) {
return url;
}
if (url.startsWith('http://') || url.startsWith('https://')) {
const baseUrl = url.replace(/\/$/, '');
const versionUrl = `${baseUrl}/json/version`;
logger?.debug?.(`Resolving WebSocket URL from ${versionUrl}`);
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000);
try {
const response = await fetch(versionUrl, { signal: controller.signal });
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}`);
}
logger?.debug?.(`Resolved WebSocket URL: ${data.webSocketDebuggerUrl}`);
return data.webSocketDebuggerUrl;
} catch (error) {
if (error instanceof Error && error.name === 'AbortError') {
throw new Error(`Timeout resolving WebSocket URL from ${versionUrl} (10s)`);
}
throw error;
} finally {
clearTimeout(timeoutId);View on GitHub (pinned to 75dd419e61)
Solutions
- Check the response status in the error: 401/403 means auth, 404/410 means the session is gone — create a new browser session
- Verify the Firecrawl API key and apiUrl configuration
- Retry the connection; if the remote browser was torn down, launch a fresh FirecrawlBrowser
- Check network/proxy interference with the versionUrl
Defensive patterns
Strategy: retry
Validate before calling
const res = await fetch(versionUrl);
if (!res.ok) console.error('CDP endpoint unhealthy:', res.status, await res.text()); Try / catch
try {
const browser = new FirecrawlBrowser(config);
} catch (e) {
if (e instanceof Error && e.message.includes('Failed to fetch CDP version info')) {
// status embedded in message; 401/403 = auth, 404/410 = recreate session
await recreateBrowserSession();
} else throw e;
} Prevention
- Pre-flight check the /json/version endpoint before constructing the browser
- Rotate API keys before expiry; treat 401/403 as auth, 404 as dead session
- Recreate browser sessions instead of reusing long-lived CDP URLs
- Log response bodies on failure to distinguish proxy vs CDP errors
When it happens
Trigger: Calling new FirecrawlBrowser(...) or accessing the browser's wsUrl when the Firecrawl-provided CDP versionUrl responds with an HTTP error status (401, 403, 404, 500, 502, etc.).
Common situations: Expired or invalid Firecrawl API key embedded in the URL; wrong or stale CDP endpoint (browser session already terminated); proxy/gateway errors between client and remote browser; misconfigured apiUrl.
Related errors
- No webSocketDebuggerUrl found in CDP version response from $
- Timeout resolving WebSocket URL from ${versionUrl} (10s)
- No browser context available for screencast
- CDP session not available for mouse injection
- CDP session not available for keyboard injection
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/f8afaec1e6b22e4a.
Report an issue: GitHub.