apify/crawlee · error

PlaywrightCrawlerOptions.launchContext.proxyUrl is not…

Error message

PlaywrightCrawlerOptions.launchContext.proxyUrl is not allowed in PlaywrightCrawler.Use PlaywrightCrawlerOptions.proxyConfiguration

What it means

PlaywrightCrawler removed support for setting a per-crawler proxy via launchContext.proxyUrl; proxying must go through a ProxyConfiguration passed as proxyConfiguration, which supports rotation and session binding. The constructor eagerly rejects the legacy option so users don't silently get no proxy.

Solutions

  1. Replace launchContext.proxyUrl with the proxyConfiguration option: new PlaywrightCrawler({ proxyConfiguration: await ProxyConfiguration.create({ proxyUrls: [...] }) }).
  2. For per-launch proxies, use ProxyConfiguration with rotation or newUrl/session handling instead of the launchContext field.

Example fix

// before
const crawler = new PlaywrightCrawler({
    launchContext: { proxyUrl: 'http://proxy.example.com:8080' },
});
// after
const proxyConfiguration = await ProxyConfiguration.create({ proxyUrls: ['http://proxy.example.com:8080'] });
const crawler = new PlaywrightCrawler({ proxyConfiguration });
Defensive patterns

Strategy: validation

Validate before calling

function assertNoLaunchProxy(options: PlaywrightCrawlerOptions) {
    if ((options as any)?.launchContext?.proxyUrl) {
        throw new Error('Use proxyConfiguration instead of launchContext.proxyUrl');
    }
}
assertNoLaunchProxy(options);
const crawler = new PlaywrightCrawler(options);

Prevention

When it happens

Trigger: Constructing new PlaywrightCrawler({ launchContext: { proxyUrl: 'http://proxy:8080' } }) in playwright-crawler.

Common situations: Migrating code from older Crawlee versions where launchContext.proxyUrl worked; following outdated tutorials or ChatGPT-generated snippets; mixing proxy config between launch options and crawler options.

Related errors


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

Appendix: source

Thrown at packages/playwright-crawler/src/internals/playwright-crawler.ts:246

        launcher: schemas.anyObject.optional(),
    };

    /** @internal */
    protected static override optionsSchema = z.strictObject(PlaywrightCrawler.optionsShape);

    /**
     * All `PlaywrightCrawler` parameters are passed via an options object.
     */
    constructor(
        options: PlaywrightCrawlerOptions<ContextExtension, ExtendedContext, Routes, StatisticStateExtension> = {},
    ) {
        const parsedOptions = parseArgument(options, PlaywrightCrawler.optionsSchema, 'PlaywrightCrawlerOptions');

        const { launchContext, headless, configuration, contextPipelineBuilder, ...browserCrawlerOptions } =
            parsedOptions;

        if (launchContext.proxyUrl) {
            throw new Error(
                'PlaywrightCrawlerOptions.launchContext.proxyUrl is not allowed in PlaywrightCrawler.' +
                    'Use PlaywrightCrawlerOptions.proxyConfiguration',
            );
        }

        if (options.browserPool) {
            // The raw options, not the parsed ones: `launchContext` has a default, so by now it is always set.
            assertBrowserPoolNotConfigured(new.target.name, {
                launchContext: options.launchContext,
                headless: options.headless,
            });
        }

        super({
            ...(browserCrawlerOptions as unknown as PlaywrightCrawlerOptions<
                ContextExtension,
                ExtendedContext,
                Routes,

View on GitHub (pinned to dbe57fb09c)