{"record":{"id":"bf1e09e31d67e1cc","repo":"n8n-io/n8n","slug":"not-connected-to-a-browser","errorCode":null,"errorMessage":"Not connected to a browser","messagePattern":"Not connected to a browser","errorType":"exception","errorClass":"NotConnectedError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/mcp-browser/src/connection.ts","lineNumber":170,"sourceCode":"\t\tif (!this.state) return; // already disconnected — idempotent\n\n\t\tconst { adapter } = this.state;\n\t\tthis.state = null;\n\t\tthis.disconnectReason = undefined;\n\n\t\ttry {\n\t\t\tawait adapter.close();\n\t\t} catch {\n\t\t\t// Browser may already be dead — that's fine\n\t\t}\n\t}\n\n\tgetConnection(): ConnectionState {\n\t\tif (!this.state) {\n\t\t\tif (this.disconnectReason) {\n\t\t\t\tthrow new ConnectionLostError(this.disconnectReason);\n\t\t\t}\n\t\t\tthrow new NotConnectedError();\n\t\t}\n\t\treturn this.state;\n\t}\n\n\tget isConnected(): boolean {\n\t\treturn this.state !== null;\n\t}\n\n\tasync shutdown(): Promise<void> {\n\t\tawait this.disconnect();\n\t}\n\n\tgetResolvedConfig(): ResolvedConfig {\n\t\treturn this.config;\n\t}\n\n\t// -------------------------------------------------------------------------\n\t// Private","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/mcp-browser/src/connection.ts#L152-L188","documentation":"NotConnectedError is thrown by getConnection() when this.state is null and this.disconnectReason is also undefined — the connection was never established (or was cleanly disconnected). This is the 'no session exists' state, distinct from an involuntary drop.","triggerScenarios":"Calling any browser tool before browser_connect was ever called, or after a clean browser_disconnect (which clears both state and disconnectReason).","commonSituations":"Agent skips the connect step and jumps straight to a snapshot or interaction tool. Post-disconnect tool call in a teardown sequence. First-call race where the tool runs before connect resolves.","solutions":["Call browser_connect first and await it before issuing any browser tool.","Ensure your tool-dispatch layer gates on connection.isConnected === true.","After disconnect(), reset any agent state that assumes a live connection."],"exampleFix":"// before — tool before connect\nconst snap = await browserSnapshot(); // getConnection -> NotConnectedError\n\n// after — connect first\nawait connection.connect();\nconst snap = await browserSnapshot();","handlingStrategy":"validation","validationCode":"if (!connection.isConnected) { await connection.connect(); }\nconst conn = connection.getConnection();","typeGuard":"function isReady(c: BrowserConnection): boolean {\n  return c.isConnected;\n}","tryCatchPattern":"try {\n  const conn = connection.getConnection();\n} catch (e) {\n  if (e instanceof NotConnectedError) { await connection.connect(); }\n  else throw e;\n}","preventionTips":["Always call and await browser_connect before any browser tool.","Gate the tool dispatcher on isConnected.","After disconnect(), reset agent state that assumes a live connection."],"tags":["not-connected","state","connect","validation"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}