{"record":{"id":"8c5661cfa3f35927","repo":"microsoft/playwright","slug":"playwright-extension-not-found-in-profiledirect","errorCode":null,"errorMessage":"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.","messagePattern":"Playwright Extension not found in \"(.+?)\"\\. Install it from (.+?), or set the PLAYWRIGHT_MCP_EXECUTABLE_PATH environment variable to use a browser at a custom location\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/tools/mcp/extensionContextFactory.ts","lineNumber":35,"sourceCode":"import path from 'path';\n\nimport debug from 'debug';\nimport { defaultUserDataDirForChannel } from '@utils/chromiumChannels';\nimport { playwright } from '../../inprocess';\nimport { findPlaywrightExtensionProfile, isExtensionInstalledInProfile, playwrightExtensionInstallUrl } from '../utils/extension';\nimport { CDPRelayServer } from './cdpRelay';\n\nimport type * as playwrightTypes from '../../..';\n\nconst debugLogger = debug('pw:mcp:relay');\n\nexport async function createExtensionBrowser(channel: string, executablePath: string | undefined, customUserDataDir: string | undefined, profileDirName: string | undefined, clientName: string): Promise<playwrightTypes.Browser> {\n  customUserDataDir ??= process.env.PWTEST_EXTENSION_USER_DATA_DIR;\n  // 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.\n  const userDataDir = customUserDataDir ?? (executablePath ? undefined : defaultUserDataDirForChannel(channel));\n  const profileDirectory = profileDirName ?? (userDataDir ? await findPlaywrightExtensionProfile(userDataDir) : undefined);\n  if (userDataDir && !executablePath && (!profileDirectory || !await isExtensionInstalledInProfile(path.join(userDataDir, profileDirectory))))\n    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.`);\n\n  const relay = new CDPRelayServer(channel, executablePath, customUserDataDir, profileDirectory);\n  await relay.start();\n  debugLogger(`CDP relay server started, extension endpoint: ${relay.extensionEndpoint()}.`);\n\n  try {\n    await relay.establishExtensionConnection(clientName);\n    const browser = await playwright.chromium.connectOverCDP(relay.cdpEndpoint(), { isLocal: true, timeout: 0, noDefaults: true });\n    browser.on('disconnected', () => relay.stop());\n    return browser;\n  } catch (error) {\n    relay.stop();\n    throw error;\n  }\n}\n","sourceCodeStart":17,"sourceCodeEnd":51,"githubUrl":"https://github.com/microsoft/playwright/blob/312030cdcee20c006343e5f8420fe451b9aa6390/packages/playwright-core/src/tools/mcp/extensionContextFactory.ts#L17-L51","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nnpx @playwright/mcp --extension # profile has no extension\n// after\nexport PLAYWRIGHT_MCP_EXECUTABLE_PATH=/path/to/chrome-with-extension\nnpx @playwright/mcp --extension","handlingStrategy":"validation","validationCode":"const userDataDir = process.env.PWTEST_EXTENSION_USER_DATA_DIR ?? defaultUserDataDirForChannel(channel);\nconst profile = await findPlaywrightExtensionProfile(userDataDir);\nif (!profile || !(await isExtensionInstalledInProfile(path.join(userDataDir, profile)))) {\n  throw new Error(`Playwright extension missing in ${path.join(userDataDir, profile ?? userDataDir)}. Install it before launching.`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const browser = await createExtensionBrowser(channel, executablePath, userDataDir, profileDir, clientName);\n} catch (e) {\n  if (String(e.message).includes('Playwright Extension not found')) {\n    console.error('Install the extension from the URL in the error, or set PLAYWRIGHT_MCP_EXECUTABLE_PATH to a browser that has it.');\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["mcp","extension","missing-dependency","chrome-profile"],"backgroundTag":"entity-not-found","analyzedSha":"312030cdcee20c006343e5f8420fe451b9aa6390","analyzedAt":"2026-09-07T14:42:43.271Z","contentChangedAt":"2026-09-07T14:42:43.271Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}