apify/crawlee · error · BrowserLaunchError

${errorMessage.join(' ')}​

Error message

${errorMessage.join('
')}​

What it means

throwAugmentedLaunchError builds a multi-line diagnostic report (launch options, proxy info, and the underlying launch error) and throws it as a single BrowserLaunchError whose message is the joined lines, terminated with a zero-width space used later when printing the stack. The real cause is in `error.cause`; the message is the augmented, human-readable launch failure report. Called when the plugin detects that its launch attempt failed (throwOnFailedLaunch) or directly from _launch paths.

Source

Thrown at packages/browser-pool/src/abstract-classes/browser-plugin.ts:322

        if (executablePath) {
            errorMessage.push(`- Check whether the provided executable path "${executablePath}" is correct.`);
        }

        if (process.env.APIFY_IS_AT_HOME) {
            errorMessage.push(`- Make sure your Dockerfile extends ${dockerImage}.`);
        }

        errorMessage.push(`- ${moduleInstallCommand}`);

        errorMessage.push(
            '',
            'The original error is available in the `cause` property. Below is the error received when trying to launch a browser:',
            '',
        );

        // Add in a zero-width space so we can remove it later when printing the error stack
        throw new BrowserLaunchError(`${errorMessage.join('\n')}\u200b`, { cause });
    }

    /**
     * @private
     */
    protected abstract addProxyToLaunchOptions(
        launchContext: LaunchContext<Library, LibraryOptions, LaunchResult, NewPageOptions, NewPageResult>,
    ): Promise<void>;

    protected abstract isChromiumBasedBrowser(
        launchContext: LaunchContext<Library, LibraryOptions, LaunchResult, NewPageOptions, NewPageResult>,
    ): boolean;

    /**
     * @private
     */
    protected abstract _launch(
        launchContext: LaunchContext<Library, LibraryOptions, LaunchResult, NewPageOptions, NewPageResult>,

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Read the full multi-line message — it contains the exact launch options and the original error text above the marker line.
  2. Inspect error.cause for the raw error.
  3. Install/download the correct browser executable (e.g. `npx playwright install chromium`).
  4. Fix or remove invalid launchOptions/args and proxy configuration.
  5. Check the zero-width space note: when matching on the message programmatically, strip the trailing \u200b.

Example fix

// before
// message ends with an invisible zero-width space, exact string compare fails
if (err.message === 'Failed to launch browser.') { ... }
// after
const clean = err.message.replace(/\u200b/g, '');
if (clean.includes('Failed to launch')) {
    console.error('launch report:', clean, '\ncause:', err.cause);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-launch: ensure the browser binary exists
import { executablePath } from 'playwright';
if (!existsSync(executablePath())) await run('npx playwright install chromium');

Try / catch

try {
    const page = await pool.newPage();
} catch (err) {
    if (err instanceof BrowserLaunchError) {
        console.error(err.message.replace(/\u200b/g, '')); // full launch report
        console.error('root cause:', err.cause);
    } else throw err;
}

Prevention

When it happens

Trigger: Any browser launch failure routed through the plugin's failure detection: missing/unsupported browser executable, incompatible browser version, invalid launch options, proxy misconfiguration, or the underlying library (Playwright/Puppeteer) rejecting launch().

Common situations: First run in an environment where the browser binary was never downloaded; Docker images without the needed system libraries; launch args rejected by a newer/older browser version; proxy env variables malformed.

Related errors


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