apify/crawlee · error
Failed to get CDP URL from Stagehand
Error message
Failed to get CDP URL from Stagehand
What it means
In StagehandPlugin._launch(), after stagehand.init() the plugin asks Stagehand for a CDP endpoint via stagehand.connectURL() so Playwright can attach to the same browser. If connectURL() returns a falsy value (Stagehand did not expose an endpoint), the plugin throws because connecting without the URL is impossible.
Source
Thrown at packages/stagehand-crawler/src/internals/stagehand-plugin.ts:101
proxy: anonymizedProxyUrl ? { server: anonymizedProxyUrl } : launchOptions.proxy,
viewport: (launchOptions as Record<string, unknown>).viewport as {
width: number;
height: number;
},
}
: undefined,
};
const stagehand = new Stagehand(stagehandConfig);
try {
// Initialize Stagehand (launches browser)
await stagehand.init();
// Get CDP URL and connect Playwright to the same browser
const cdpUrl = stagehand.connectURL();
if (!cdpUrl) {
throw new Error('Failed to get CDP URL from Stagehand');
}
const browser = await chromium.connectOverCDP(cdpUrl);
// Store the Stagehand instance for AI operations
this.#stagehandInstances.set(browser, stagehand);
// Handle browser disconnection - cleanup both Stagehand and anonymized proxy
browser.on('disconnected', async () => {
await this.cleanupStagehand(browser);
await closeAnonymizedProxy();
});
return browser;
} catch (error) {
// Clean up on failure
await stagehand.close().catch(() => {});
await closeAnonymizedProxy();View on GitHub (pinned to dbe57fb09c)
Solutions
- Check the Stagehand version supports connectURL() and that it returns a ws/http endpoint after init()
- Configure Stagehand to launch a connectable browser (CDP-capable local Chromium) — avoid configs that bypass an exposed endpoint
- Log the cdpUrl after init() to see whether Stagehand reports one at all
- Pin compatible versions of @browserbasehq/stagehand with @crawlee/stagehand-crawler
- Ensure stagehand.init() completed without swallowed errors before connectURL()
Example fix
// before
const stagehand = new Stagehand({ env: 'LOCAL', browserbaseResolveWSEndpoint: false, /* non-CDP mode */ });
await stagehand.init();
// after
const stagehand = new Stagehand({ env: 'LOCAL', /* default local chromium exposes CDP endpoint */ });
await stagehand.init();
const cdpUrl = stagehand.connectURL();
if (!cdpUrl) throw new Error('connectURL unavailable for this stagehand config'); Defensive patterns
Strategy: validation
Validate before calling
const cdpUrl = stagehand.connectURL();
if (typeof cdpUrl !== 'string' || cdpUrl.length === 0) {
throw new Error('Stagehand did not expose a CDP URL; check env/config before launching the crawler');
} Type guard
const hasCdpUrl = (stagehand) => typeof stagehand?.connectURL === 'function' && !!stagehand.connectURL();
Try / catch
try {
await plugin._launch();
} catch (err) {
if (err.message === 'Failed to get CDP URL from Stagehand') {
log.error('connectURL() empty — verify Stagehand mode/version supports CDP endpoints');
}
throw err;
} Prevention
- Pin a Stagehand version known to support connectURL()
- Use a browser mode that exposes a CDP endpoint (default local Chromium)
- Log cdpUrl right after init() in CI smoke tests
- Ensure init() succeeded before calling connectURL()
When it happens
Trigger: stagehand.connectURL() returning undefined/empty — typically when the Stagehand config uses LOCAL browser mode where connectURL is unsupported, an incompatible @browserbasehq/stagehand version, or init() partially failed leaving the browser endpoint unset.
Common situations: Upgrading stagehand where connectURL() semantics changed, running in environments where Stagehand falls back to a mode without a connectable endpoint (e.g. some local launch setups), or env vars forcing a non-CDP browser mode.
Related errors
- No browser context available
- Stagehand did not register the page within ${timeoutMs}ms
- Function `newBrowserCDPSession()` is not available in incogn
- Cannot detect CDP client for Puppeteer ${parsed.version}. Yo
- Stagehand instance not found for browser
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/03d676f87149d4de.
Report an issue: GitHub.