n8n-io/n8n · critical · ConnectionLostError

Browser connection lost: The browser extension disconnected

Error message

Browser connection lost: The browser extension disconnected

What it means

ConnectionLostError('extension_disconnected') is thrown in the Target.attachToTarget CDP handler when this.extensionConn is null. The relay translates Playwright's CDP Target.attachToTarget into an extension 'attachTab' message; if the extension WebSocket is gone, the translation cannot proceed. This indicates the extension side of the bridge dropped.

Source

Thrown at packages/@n8n/mcp-browser/src/cdp-relay.ts:433

				const tabs = await this.listTabs();
				return {
					targetInfos: tabs.map((entry) => ({
						targetId: entry.id,
						type: 'page',
						title: entry.title,
						url: entry.url,
						attached: false,
						browserContextId: this.browserContextId,
					})),
				};
			}

			case 'Target.setDiscoverTargets':
				return {};

			case 'Target.attachToTarget': {
				const targetId = (params as { targetId: string })?.targetId;
				if (!this.extensionConn) throw new ConnectionLostError('extension_disconnected');
				await this.extensionConn.send('attachTab', { id: targetId });
				return { sessionId: targetId };
			}

			case 'Target.setAutoAttach': {
				// Child session auto-attach: forward to extension so Chrome attaches to iframes
				if (sessionId) {
					return await this.forwardToExtension(method, params, sessionId);
				}

				// Root-level: forward to extension (applies to all attached tabs) AND list tabs for cache
				log.debug('Target.setAutoAttach: forwarding to extension and listing tabs');
				await this.forwardToExtension(method, params, sessionId);

				const { tabs } = (await this.extensionConn!.send('listRegisteredTabs', {})) as {
					tabs: Array<{ id: string; title: string; url: string }>;
				};
				log.debug('listRegisteredTabs result:', tabs.length, 'tabs');

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Call browser_disconnect then browser_connect to re-establish the extension bridge.
  2. Ensure the n8n AI Browser Bridge extension is installed, enabled, and not suspended (Chrome service-worker eviction).
  3. Keep the session active with periodic interaction to prevent service-worker suspension.

Example fix

// before — operating after extension dropped
await connection.getConnection(); // ConnectionLostError propagates

// after — reconnect
await connection.disconnect();
await connection.connect();
Defensive patterns

Strategy: retry

Validate before calling

if (!relay.extensionConn) { await connection.disconnect(); await connection.connect(); }

Type guard

function extensionAlive(relay: CdpRelay): boolean {
  return relay.extensionConn !== null;
}

Try / catch

try {
  await relay.handleCdp('Target.attachToTarget', params);
} catch (e) {
  if (e instanceof ConnectionLostError) {
    await connection.disconnect();
    await connection.connect();
    await relay.handleCdp('Target.attachToTarget', params);
  } else throw e;
}

Prevention

When it happens

Trigger: Playwright issues Target.attachToTarget (during page auto-attach or explicit attach) after the extension connection was closed — e.g. the extension was uninstalled, the browser was quit, or the WebSocket closed and extensionConn was nulled on close.

Common situations: User closed the browser while a session was active. Extension crashed or was reloaded. Network interruption dropped the WebSocket and handleClose() nulled extensionConn. Long-idle session where the extension's service worker was evicted.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/7f1749c7aa21947a. Report an issue: GitHub.