{"record":{"id":"cc4a1abb7ef9a1d3","repo":"continuedev/continue","slug":"mcp-connection-serverid-not-found","errorCode":null,"errorMessage":"MCP Connection ${serverId} not found","messagePattern":"MCP Connection (.+?) not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"core/context/mcp/MCPManagerSingleton.ts","lineNumber":147,"sourceCode":"\n  private compareEnv(\n    aEnv: Record<string, string> | undefined,\n    bEnv: Record<string, string> | undefined,\n  ): boolean {\n    const a = aEnv ?? {};\n    const b = bEnv ?? {};\n    const aKeys = Object.keys(a);\n    const bKeys = Object.keys(b);\n\n    return (\n      aKeys.length === bKeys.length && aKeys.every((key) => a[key] === b[key])\n    );\n  }\n\n  async refreshConnection(serverId: string) {\n    const connection = this.connections.get(serverId);\n    if (!connection) {\n      throw new Error(`MCP Connection ${serverId} not found`);\n    }\n    await connection.connectClient(true, this.abortController.signal);\n    if (this.onConnectionsRefreshed) {\n      this.onConnectionsRefreshed();\n    }\n  }\n\n  async refreshConnections(force: boolean) {\n    this.abortController.abort();\n    this.abortController = new AbortController();\n    await Promise.race([\n      new Promise((resolve) => {\n        this.abortController.signal.addEventListener(\"abort\", () => {\n          resolve(undefined);\n        });\n      }),\n      (async () => {\n        await Promise.all(","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/continuedev/continue/blob/5522c6f44ca0ac3528b37244818fbfa39b5af470/core/context/mcp/MCPManagerSingleton.ts#L129-L165","documentation":"Identical guard to the non-streaming path, applied in chatCompletionStream: Vertex AI express (apiKey) auth only works for Gemini models, and streaming requests for anthropic/mistral models are rejected before any network call.","triggerScenarios":"config.apiKey set and a streaming completion requested with a claude-* or mistral/codestral model via completionStream.","commonSituations":"Streaming pipelines configured with a Vertex API key, then the model is switched to Claude or Codestral on Vertex without changing auth.","solutions":["Use service-account auth (keyJson/keyFile/ADC) for non-gemini streaming models","Or stream a gemini-* model in express mode","Keep separate adapter instances per auth mode/model family"],"exampleFix":"// before\nconst api = new VertexAIApi({ apiKey: KEY });\nfor await (const c of api.chatCompletionStream({ model: 'claude-3-5-sonnet@...', ... }, signal)) {}\n\n// after\nconst api = new VertexAIApi({ keyJson: SA_JSON });\nfor await (const c of api.chatCompletionStream({ model: 'claude-3-5-sonnet@...', ... }, signal)) {}","handlingStrategy":"validation","validationCode":"if (hasApiKey && !/gemini/i.test(body.model)) throw new Error('configure service-account auth for non-gemini streaming');","typeGuard":"const isGeminiModel = (m: string): boolean => /gemini/i.test(m);","tryCatchPattern":"try { for await (const c of api.chatCompletionStream(body, signal)) {} } catch (e) { if ((e as Error).message.includes('express (apiKey) mode')) { /* reauth with keyJson or switch model */ } throw e; }","preventionTips":["Bind auth mode to model family at config time","Integration-test each model family against its auth mode"],"tags":["vertexai","streaming","api-key","express-mode"],"backgroundTag":"auth-mode-unsupported-for-model","analyzedSha":"5522c6f44ca0ac3528b37244818fbfa39b5af470","analyzedAt":"2026-08-27T11:28:54.683Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}