microsoft/playwright · error · Error

Playwright Extension not found in "${profileDirectory ? path

Error message

Playwright Extension not found in "${profileDirectory ? path.join(userDataDir, profileDirectory) : 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

`createExtensionBrowser` verifies that the Playwright extension is actually installed in the resolved Chrome user-data-dir profile before starting the CDP relay. When a default (or custom) user data dir is used, no executable path override is given, and `findPlaywrightExtensionProfile`/`isExtensionInstalledInProfile` finds no installed extension, this error is thrown with the exact profile path checked and the install URL.

Source

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

import path from 'path';

import debug from 'debug';
import { defaultUserDataDirForChannel } from '@utils/chromiumChannels';
import { playwright } from '../../inprocess';
import { findPlaywrightExtensionProfile, isExtensionInstalledInProfile, 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, profileDirName: 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 = profileDirName ?? (userDataDir ? await findPlaywrightExtensionProfile(userDataDir) : undefined);
  if (userDataDir && !executablePath && (!profileDirectory || !await isExtensionInstalledInProfile(path.join(userDataDir, profileDirectory))))
    throw new Error(`Playwright Extension not found in "${profileDirectory ? path.join(userDataDir, profileDirectory) : 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 312030cdce)

Solutions

  1. Install the Playwright extension from the URL in the error message (playwrightExtensionInstallUrl) into the reported Chrome profile.
  2. Set `PLAYWRIGHT_MCP_EXECUTABLE_PATH` to a browser executable whose profile already has the extension installed.
  3. Verify the resolved profile path in the message actually contains the extension's manifest (check the stated directory).
  4. If using a custom user data dir, ensure `findPlaywrightExtensionProfile` can locate the extension profile inside it.
  5. For WSL2 setups, confirm the extension is installed in the Windows-side Chrome profile matching the resolved userDataDir, or rely on the executablePath override.

Example fix

// before
npx @playwright/mcp --extension # profile has no extension
// after
export PLAYWRIGHT_MCP_EXECUTABLE_PATH=/path/to/chrome-with-extension
npx @playwright/mcp --extension
Defensive patterns

Strategy: validation

Validate before calling

const userDataDir = process.env.PWTEST_EXTENSION_USER_DATA_DIR ?? defaultUserDataDirForChannel(channel);
const profile = await findPlaywrightExtensionProfile(userDataDir);
if (!profile || !(await isExtensionInstalledInProfile(path.join(userDataDir, profile)))) {
  throw new Error(`Playwright extension missing in ${path.join(userDataDir, profile ?? userDataDir)}. Install it before launching.`);
}

Try / catch

try {
  const browser = await createExtensionBrowser(channel, executablePath, userDataDir, profileDir, clientName);
} catch (e) {
  if (String(e.message).includes('Playwright Extension not found')) {
    console.error('Install the extension from the URL in the error, or set PLAYWRIGHT_MCP_EXECUTABLE_PATH to a browser that has it.');
  }
  throw e;
}

Prevention

When it happens

Trigger: Launching the MCP extension browser where: the resolved `userDataDir` exists but no profile directory contains the Playwright extension; `profileDirName` points to a profile without the extension; or the channel's default user data dir was never provisioned with the extension. Only skipped when a custom `executablePath` (e.g. `PLAYWRIGHT_MCP_EXECUTABLE_PATH`) is set.

Common situations: Fresh machines/CI containers lacking the extension in the default Chrome profile; running Chrome via WSL2 with a Windows executable and a mismatched profile path; wiping the Chrome user data dir and forgetting to reinstall the extension; pointing `PLAYWRIGHT_MCP_EXECUTABLE_PATH` at a browser whose profile has no extension.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of microsoft/playwright@312030cdce (2026-09-07). Data as JSON: /api/errors/8c5661cfa3f35927. Report an issue: GitHub.