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

  1. Check the Stagehand version supports connectURL() and that it returns a ws/http endpoint after init()
  2. Configure Stagehand to launch a connectable browser (CDP-capable local Chromium) — avoid configs that bypass an exposed endpoint
  3. Log the cdpUrl after init() to see whether Stagehand reports one at all
  4. Pin compatible versions of @browserbasehq/stagehand with @crawlee/stagehand-crawler
  5. 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

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


AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30). Data as JSON: /api/errors/03d676f87149d4de. Report an issue: GitHub.