{"record":{"id":"62a1341542b03d53","repo":"google-gemini/gemini-cli","slug":"failed-to-initialize-chrome-devtools-mcp-client","errorCode":null,"errorMessage":"Failed to initialize chrome-devtools MCP client","messagePattern":"Failed to initialize chrome-devtools MCP client","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/agents/browser/browserManager.ts","lineNumber":298,"sourceCode":"  constructor(private config: Config) {\n    const browserConfig = config.getBrowserAgentConfig();\n    this.shouldInjectOverlay = !browserConfig?.customConfig?.headless;\n    this.shouldDisableInput = config.shouldDisableBrowserUserInput();\n    this.maxActionsPerTask =\n      browserConfig?.customConfig.maxActionsPerTask ?? 100;\n  }\n\n  /**\n   * Gets the raw MCP SDK Client for direct tool calls.\n   * This client is ISOLATED from the main tool registry.\n   */\n  async getRawMcpClient(): Promise<Client> {\n    if (this.rawMcpClient) {\n      return this.rawMcpClient;\n    }\n    await this.ensureConnection();\n    if (!this.rawMcpClient) {\n      throw new Error('Failed to initialize chrome-devtools MCP client');\n    }\n    return this.rawMcpClient;\n  }\n\n  /**\n   * Gets the tool definitions discovered from the MCP server.\n   * These are dynamically fetched from chrome-devtools-mcp.\n   */\n  async getDiscoveredTools(): Promise<McpTool[]> {\n    await this.ensureConnection();\n    return this.discoveredTools;\n  }\n\n  /**\n   * Calls a tool on the MCP server.\n   *\n   * @param toolName The name of the tool to call\n   * @param args Arguments to pass to the tool","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/google-gemini/gemini-cli/blob/5024443c7217464a66e98f80d73172a26440bd8f/packages/core/src/agents/browser/browserManager.ts#L280-L316","documentation":"Defensive guard in getRawMcpClient(): after awaiting ensureConnection(), rawMcpClient is still undefined. Normally connectMcp() (called via connectWithRetry) assigns this.rawMcpClient; reaching this throw means connection setup returned without ever setting the client — typically a race with close() or an internal logic gap.","triggerScenarios":"getRawMcpClient() is called when isConnected() is false, ensureConnection() runs, but during the connect sequence close() was invoked concurrently (setting rawMcpClient=undefined), or connectMcp threw in a way that left state inconsistent yet connectWithRetry resolved.","commonSituations":"BrowserManager.close() racing a pending tool call (e.g. /clear or CLI exit during an in-flight browser action); a reconnect cycle interrupted by teardown; very rare under normal use — usually indicates a lifecycle bug or concurrent shutdown.","solutions":["Avoid issuing browser tool calls while the session/CLI is being torn down; drain in-flight calls before close().","If seen persistently, check that connectMcp() is not swallowing the assignment — ensure this.rawMcpClient is set before any awaited step that can throw.","Retry the call after the connection settles; ensureConnection() will re-run connectWithRetry.","Report as an internal bug if reproducible, including the chrome-devtools-mcp stderr from debug logs."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Ensure connection is healthy before relying on the client.\nasync function safeGetClient(bm) {\n  if (!bm.isConnected()) await bm.ensureConnection();\n  return bm.getRawMcpClient();\n}","typeGuard":null,"tryCatchPattern":"try {\n  const client = await bm.getRawMcpClient();\n} catch (e) {\n  if (e instanceof Error && /Failed to initialize chrome-devtools MCP client/.test(e.message)) {\n    // connection raced with close(); reconnect and retry once\n    await bm.ensureConnection();\n    return bm.getRawMcpClient();\n  }\n  throw e;\n}","preventionTips":["Do not issue browser calls during teardown/close.","Drain in-flight browser operations before calling close()/resetAll().","Check isConnected() before heavy operations."],"tags":["browser","mcp","lifecycle","race-condition"],"backgroundTag":null,"analyzedSha":"5024443c7217464a66e98f80d73172a26440bd8f","analyzedAt":"2026-08-12T06:01:53.711Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}