microsoft/playwright · error · Error
Extension not connected
Error message
Extension not connected
What it means
Thrown inside the CdpRelay's `sendCommand` closure whenever a command is dispatched before `this._extensionConnection` has been set (the extension WebSocket has not yet connected). The relay routes every Playwright→extension command through that connection, so a missing connection is a hard precondition failure.
Source
Thrown at packages/playwright-core/src/tools/mcp/cdpRelay.ts:83
private _profileDirectory?: string;
private _cdpPath: string;
private _extensionPath: string;
private _cdpConnection: WebSocket | null = null;
private _extensionConnection: ExtensionConnection | null = null;
private _protocolVersion: number;
private _handler: ExtensionProtocolV2;
private _extensionConnectionPromise = new ManualPromise<void>();
constructor(browserChannel: string, executablePath?: string, customUserDataDir?: string, profileDirectory?: string) {
this._browserChannel = browserChannel;
this._executablePath = executablePath;
this._customUserDataDir = customUserDataDir;
this._profileDirectory = profileDirectory;
this._protocolVersion = parseInt(process.env.PLAYWRIGHT_EXTENSION_PROTOCOL ?? protocol.VERSION.toString(), 10);
const sendCommand = (method: string, params: any): Promise<any> => {
if (!this._extensionConnection)
throw new Error('Extension not connected');
return this._extensionConnection.send(method as keyof ExtensionCommandV2, params);
};
this._handler = new ExtensionProtocolV2(sendCommand);
const uuid = crypto.randomUUID();
this._cdpPath = `/cdp/${uuid}`;
this._extensionPath = `/extension/${uuid}`;
void this._extensionConnectionPromise.catch(logUnhandledError);
this._wsServer = new WSServer({
onRequest: (request, response) => {
response.statusCode = 404;
response.end();
},
onHeaders: () => {},
onUpgrade: () => undefined,
isAllowedPathname: pathname => pathname === this._cdpPath || pathname === this._extensionPath,
onConnection: (request, url, ws) => {View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Complete the extension connection flow first — `await relay.establishExtensionConnection(clientName)` — before driving the browser.
- Verify the extension is installed, enabled, and that the connect page was accepted by the user.
- If a token is configured (`PLAYWRIGHT_MCP_EXTENSION_TOKEN`), ensure the extension sends the matching token.
Defensive patterns
Strategy: validation
Validate before calling
// Only send commands once the extension connection is established.
let extensionReady = false;
relay.onExtensionConnected(() => { extensionReady = true; });
function assertExtensionReady() {
if (!extensionReady) throw new Error('Extension not connected yet; complete the connect flow first.');
} Try / catch
try {
await cdpRelay.someCommand(...);
} catch (e) {
if (/Extension not connected/.test((e as Error).message)) {
await relay.establishExtensionConnection(clientName); // guide user through connect
await cdpRelay.someCommand(...);
} else throw e;
} Prevention
- Always await establishExtensionConnection before issuing commands.
- Confirm the extension is enabled and the user approved the connect page.
- Match the token if PLAYWRIGHT_MCP_EXTENSION_TOKEN is set.
When it happens
Trigger: Any CDP/command traffic is generated before `_handleExtensionConnection` has wired up `_extensionConnection`, i.e. before `establishExtensionConnection` resolves. This can happen if Playwright connects to the CDP endpoint and starts sending commands before the extension side has dialed in.
Common situations: The user has not yet approved/connected the browser extension; the extension failed to connect (network blocked, wrong token, extension disabled); a race where the CDP client connects and issues commands immediately while the extension handshake is still pending.
Related errors
- Unexpected WebSocket state: ${this._ws.readyState}
- Failed to create tab
- Unsupported channel: "${this._browserChannel}"
- "${this._browserChannel}" executable not found. Make sure it
- "${parts[0].name}" selector cannot be first
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/24fe1ae2ef147ed2.
Report an issue: GitHub.