{"record":{"id":"1ccfd4f3f1c2022a","repo":"n8n-io/n8n","slug":"browser-connection-lost-the-connection-to-the-bro","errorCode":null,"errorMessage":"Browser connection lost: The connection to the browser extension was lost","messagePattern":"Browser connection lost: The connection to the browser extension was lost","errorType":"exception","errorClass":"ConnectionLostError","httpStatus":null,"severity":"critical","filePath":"packages/@n8n/mcp-browser/src/cdp-relay.ts","lineNumber":953,"sourceCode":"\t\t});\n\t\tthis.ws.on('error', (error) => {\n\t\t\tlog.debug('ExtensionConnection WebSocket error:', error);\n\t\t\tthis.handleClose();\n\t\t});\n\t\tthis.ws.on('pong', () => {\n\t\t\tthis.lastPongAt = Date.now();\n\t\t});\n\n\t\tthis.startHeartbeat();\n\t}\n\n\tasync send<M extends keyof ExtensionCommands>(\n\t\tmethod: M,\n\t\tparams: ExtensionCommands[M]['params'],\n\t\ttimeoutMs = 30_000,\n\t): Promise<unknown> {\n\t\tif (this.ws.readyState !== WebSocket.OPEN) {\n\t\t\tthrow new ConnectionLostError('network_error');\n\t\t}\n\n\t\tconst id = ++this.lastId;\n\t\tconst payload = JSON.stringify({ id, method, params });\n\t\tlog.debug('→ EXT:', method, 'id=' + String(id));\n\t\ttry {\n\t\t\tthis.ws.send(payload);\n\t\t} catch {\n\t\t\tthrow new ConnectionLostError('network_error');\n\t\t}\n\n\t\treturn await new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.callbacks.delete(id);\n\t\t\t\tlog.error(\n\t\t\t\t\t'→ EXT TIMEOUT:',\n\t\t\t\t\tmethod,\n\t\t\t\t\t'id=' + String(id),","sourceCodeStart":935,"sourceCodeEnd":971,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/mcp-browser/src/cdp-relay.ts#L935-L971","documentation":"ConnectionLostError('network_error') is thrown at the top of ExtensionConnection.send when the WebSocket readyState is not OPEN. Before queueing any request to the extension, send() checks the socket; a non-OPEN state (CONNECTING, CLOSING, CLOSED) means the channel is unusable. This is the pre-flight guard before any bytes are written.","triggerScenarios":"Issuing any extension command (attachTab, createTab, forwardCDPCommand, etc.) when the WebSocket has transitioned out of OPEN — after handleClose fired, after close() was called, or while the socket is still handshaking.","commonSituations":"Command issued immediately after construction before the WS finishes opening. Command issued after the OS reported the TCP connection dead. Race between the disconnect event and an in-flight caller.","solutions":["Wait for the connection open event before issuing commands, or reconnect via browser_connect.","Track connection liveness and queue/retry commands only while OPEN.","Call browser_disconnect then browser_connect to obtain a fresh ExtensionConnection."],"exampleFix":"// before — send before socket open\nextConn.send('createTab', { url }); // readyState=CLOSED -> throws\n\n// after — reconnect to get a fresh OPEN socket\nawait connection.disconnect(); await connection.connect();\nawait extConn.send('createTab', { url });","handlingStrategy":"validation","validationCode":"if (extConn.ws.readyState !== WebSocket.OPEN) {\n  await connection.disconnect();\n  await connection.connect();\n}","typeGuard":"function socketOpen(ws: WebSocket): boolean {\n  return ws.readyState === WebSocket.OPEN;\n}","tryCatchPattern":"try {\n  return await extConn.send(method, params);\n} catch (e) {\n  if (e instanceof ConnectionLostError && e.reason === 'network_error') {\n    await connection.disconnect();\n    await connection.connect();\n    return await extConn.send(method, params);\n  }\n  throw e;\n}","preventionTips":["Wait for the WebSocket open event before issuing the first command.","Track readyState transitions and reconnect before the next send.","Do not reuse an ExtensionConnection after its socket closed."],"tags":["connection-lost","network","websocket","send"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}