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
- Install the Playwright extension from the URL in the error message (playwrightExtensionInstallUrl) into the reported Chrome profile.
- Set `PLAYWRIGHT_MCP_EXECUTABLE_PATH` to a browser executable whose profile already has the extension installed.
- Verify the resolved profile path in the message actually contains the extension's manifest (check the stated directory).
- If using a custom user data dir, ensure `findPlaywrightExtensionProfile` can locate the extension profile inside it.
- 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
- Provision the extension into the Chrome profile as part of environment setup (Dockerfile/CI script).
- Prefer PLAYWRIGHT_MCP_EXECUTABLE_PATH pointing at a browser known to have the extension.
- After wiping a Chrome user data dir, always reinstall the extension.
- In WSL2 setups, keep the extension and executable path pointing at the same side's profile.
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
- Playwright Extension not found in "${userDataDir}". Install
- Playwright extension did not connect within ${extensionConne
- Failed to create tab
- No attached tab to forward browser-level command: ${method}
- No tab found for sessionId: ${sessionId}
AI-assisted analysis of microsoft/playwright@312030cdce (2026-09-07).
Data as JSON: /api/errors/8c5661cfa3f35927.
Report an issue: GitHub.