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
- Install the Playwright browser extension from the URL shown in the error message into the target browser profile, then retry.
- Set PLAYWRIGHT_MCP_EXECUTABLE_PATH to a browser binary if you want to bypass extension discovery and point at a specific browser.
- 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.
- 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
- Run the extension install step as part of environment setup, documented in onboarding.
- Set PLAYWRIGHT_MCP_EXECUTABLE_PATH in CI to bypass extension discovery entirely.
- Confirm the channel and profile match where the extension was installed.
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
- Device emulation is not supported with cdpEndpoint.
- page: expected Page or Frame
- CDP session is only available in Chromium
- Tracing is only available in Chromium
- No attached tab to forward browser-level command: ${method}
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/e09390ea9ec8822b.
Report an issue: GitHub.