apify/crawlee · error · Error

Function `newContext()` is not available in incognito mode

Error message

Function `newContext()` is not available in incognito mode

What it means

When a Playwright browser is opened in incognito mode, the wrapper represents the incognito BrowserContext itself, so there is no separate browser-level context to create. Calling newContext() on it is therefore unsupported and always throws. Use newPage() to create pages directly within the existing incognito context.

Source

Thrown at packages/browser-pool/src/playwright/playwright-browser.ts:66

    version(): string {
        return this.#version;
    }

    /** @internal */
    setBrowserType(browserType: BrowserType): void {
        this.#browserType = browserType;
    }

    browserType(): BrowserType {
        return this.#browserType!;
    }

    async newPage(...args: Parameters<BrowserContext['newPage']>): ReturnType<BrowserContext['newPage']> {
        return this.#browserContext.newPage(...args);
    }

    async newContext(): Promise<never> {
        throw new Error('Function `newContext()` is not available in incognito mode');
    }

    async newBrowserCDPSession(): Promise<never> {
        throw new Error('Function `newBrowserCDPSession()` is not available in incognito mode');
    }

    async startTracing(): Promise<never> {
        throw new Error('Function `startTracing()` is not available in incognito mode');
    }

    async stopTracing(): Promise<never> {
        throw new Error('Function `stopTracing()` is not available in incognito mode');
    }
}

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Call newPage() on the controller instead of newContext() — each page already gets the context options applied in incognito mode.
  2. If you need real separate contexts, set useIncognitoPages: false and use the regular browser's newContext().
  3. Restructure isolation needs around per-page context options (cookie/storage setup via contextOptions passed to newPage).

Example fix

// before
const context = await browserController.newContext();
const page = await context.newPage();
// after
const page = await browserController.newPage(); // incognito context handles isolation
Defensive patterns

Strategy: validation

Validate before calling

if (launchContext.useIncognitoPages && typeof browserController.newContext === 'function') {
  // in incognito mode newContext() throws; use newPage() instead
}

Type guard

function supportsNewContext(bc: unknown): bc is { newContext: () => Promise<unknown> } {
  return typeof (bc as { newContext?: unknown }).newContext === 'function';
}

Try / catch

try {
  await browserController.newContext();
} catch (err) {
  if (err instanceof Error && err.message.includes('not available in incognito mode')) {
    await browserController.newPage(); // fallback
  } else throw err;
}

Prevention

When it happens

Trigger: Using PlaywrightPlugin with useIncognitoPages: true and then calling browserController.newContext() (on the wrapped incognito context) to make a nested browser context.

Common situations: Porting code from a non-incognito setup where newContext() worked; trying to isolate pages into separate contexts while also using incognito pages; framework code that generically calls newContext() for isolation.

Related errors


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