microsoft/playwright · error · Error

Playwright Extension not found in "${userDataDir}". Install

Error message

Playwright Extension not found in "${userDataDir}". Install it from ${playwrightExtensionInstallUrl}, or set the PLAYWRIGHT_MCP_EXECUTABLE_PATH environment variable to use a browser at a custom location.

What it means

Thrown by createExtensionBrowser() when launching in extension mode: no custom executablePath was supplied, a user-data directory was resolved, but findPlaywrightExtensionProfile() could not locate the installed Playwright browser extension in that profile. The error points the user to the extension install URL or to PLAYWRIGHT_MCP_EXECUTABLE_PATH to point at a browser elsewhere. Extension mode requires the extension to be installed so a CDP relay can be established.

Source

Thrown at packages/playwright-core/src/tools/mcp/extensionContextFactory.ts:33

 */

import debug from 'debug';
import { defaultUserDataDirForChannel } from '@utils/chromiumChannels';
import { playwright } from '../../inprocess';
import { findPlaywrightExtensionProfile, playwrightExtensionInstallUrl } from '../utils/extension';
import { CDPRelayServer } from './cdpRelay';

import type * as playwrightTypes from '../../..';

const debugLogger = debug('pw:mcp:relay');

export async function createExtensionBrowser(channel: string, executablePath: string | undefined, customUserDataDir: string | undefined, clientName: string): Promise<playwrightTypes.Browser> {
  customUserDataDir ??= process.env.PWTEST_EXTENSION_USER_DATA_DIR;
  // Custom executablePath may target a browser in a different filesystem (e.g. Windows chrome.exe from WSL2), so the local profile path is not meaningful.
  const userDataDir = customUserDataDir ?? (executablePath ? undefined : defaultUserDataDirForChannel(channel));
  const profileDirectory = userDataDir ? await findPlaywrightExtensionProfile(userDataDir) : undefined;
  if (!executablePath && userDataDir && !profileDirectory)
    throw new Error(`Playwright Extension not found in "${userDataDir}". Install it from ${playwrightExtensionInstallUrl}, or set the PLAYWRIGHT_MCP_EXECUTABLE_PATH environment variable to use a browser at a custom location.`);

  const relay = new CDPRelayServer(channel, executablePath, customUserDataDir, profileDirectory);
  await relay.start();
  debugLogger(`CDP relay server started, extension endpoint: ${relay.extensionEndpoint()}.`);

  try {
    await relay.establishExtensionConnection(clientName);
    const browser = await playwright.chromium.connectOverCDP(relay.cdpEndpoint(), { isLocal: true, timeout: 0, noDefaults: true });
    browser.on('disconnected', () => relay.stop());
    return browser;
  } catch (error) {
    relay.stop();
    throw error;
  }
}

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Install the Playwright browser extension from the URL shown in the error message into the target browser profile, then retry.
  2. Set PLAYWRIGHT_MCP_EXECUTABLE_PATH to a browser binary if you want to bypass extension discovery and point at a specific browser.
  3. Verify the user-data-dir resolution: if you did not pass one, the code uses defaultUserDataDirForChannel(channel) — ensure that profile is the one with the extension.
  4. Confirm the browser channel (chrome/msedge/etc.) matches the profile the extension was installed into.

Example fix

// before
playwright mcp --extension
// after (point at a browser explicitly)
PLAYWRIGHT_MCP_EXECUTABLE_PATH=/usr/bin/google-chrome playwright mcp --extension
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
async function canUseExtension(channel: string, executablePath?: string, userDataDir?: string) {
  if (executablePath) return true; // bypasses profile discovery
  if (!userDataDir) userDataDir = defaultUserDataDirForChannel(channel);
  const profile = await findPlaywrightExtensionProfile(userDataDir);
  return Boolean(profile);
}

Try / catch

try {
  await createExtensionBrowser(channel, executablePath, userDataDir, clientName);
} catch (e) {
  if (/Playwright Extension not found/.test((e as Error).message)) {
    // guide the user to install the extension or fall back to a direct executable
    throw new Error('Install the Playwright extension or set PLAYWRIGHT_MCP_EXECUTABLE_PATH.');
  }
  throw e;
}

Prevention

When it happens

Trigger: Using --extension (or extension config) for the first time without having installed the Playwright browser extension into the target Chrome/Edge profile; the profile directory was reset or the extension removed; running in an environment (CI/container) where the browser profile has never had the extension added.

Common situations: First-time setup of extension mode; fresh OS/profile; extension auto-removed by the browser; pointing at a profile that belongs to a different channel than the one with the extension installed.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/e09390ea9ec8822b. Report an issue: GitHub.