{"record":{"id":"364bd2b9dcd9ebd4","repo":"Mintplex-Labs/anything-llm","slug":"anthropicllm-getchatcompletion-failed-to-communic","errorCode":null,"errorMessage":"AnthropicLLM::getChatCompletion failed to communicate with Anthropic. ${error.message}","messagePattern":"AnthropicLLM::getChatCompletion failed to communicate with Anthropic\\. (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/utils/AiProviders/anthropic/index.js","lineNumber":255,"sourceCode":"      const promptTokens = result.output.usage.input_tokens;\n      const completionTokens = result.output.usage.output_tokens;\n\n      return {\n        textResponse: result.output.content[0].text,\n        metrics: {\n          prompt_tokens: promptTokens,\n          completion_tokens: completionTokens,\n          total_tokens: promptTokens + completionTokens,\n          outputTps: completionTokens / result.duration,\n          duration: result.duration,\n          model: this.model,\n          provider: this.className,\n          timestamp: new Date(),\n        },\n      };\n    } catch (error) {\n      console.error(error);\n      throw new Error(\n        `AnthropicLLM::getChatCompletion failed to communicate with Anthropic. ${error.message}`\n      );\n    }\n  }\n\n  async streamGetChatCompletion(messages = null, { temperature = 0.7 }) {\n    await this.assertModelMaxTokens();\n    const systemContent = messages[0].content;\n    const measuredStreamRequest = await LLMPerformanceMonitor.measureStream({\n      func: this.anthropic.messages.stream({\n        model: this.model,\n        max_tokens: this.maxTokens,\n        system: this.#buildSystemPrompt(systemContent),\n        messages: messages.slice(1), // Pop off the system message\n        temperature: this.temperatureParam(temperature),\n      }),\n      messages,\n      runPromptTokenCalculation: false,","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/Mintplex-Labs/anything-llm/blob/526360e320da9d1b36074be5ed64fe76e5bbfbbd/server/utils/AiProviders/anthropic/index.js#L237-L273","documentation":"Wraps any exception thrown during the Anthropic chat-completion request and re-throws it with an `AnthropicLLM::getChatCompletion failed to communicate with Anthropic.` prefix plus the original `error.message`. The original error is also console.error'd before re-throw. It is a catch-all for upstream SDK / network / auth failures, not a single specific condition.","triggerScenarios":"Calling `getChatCompletion(messages, {temperature})` and the underlying `this.anthropic.messages.create(...)` rejects. Concrete causes: 401 invalid key, 429 rate limit, 400 from passing temperature/top_p/top_k to a model in `noTemperatureModels` (claude-opus-4-7, claude-opus-4-8, claude-sonnet-5), 404 unknown model id, DNS/TLS/ECONNRESET to api.anthropic.com, or SDK timeout.","commonSituations":"Key revoked or rotated but .env still holds the old value; selected a deprecated/renamed model id; hitting Anthropic rate limits under load; corporate proxy or firewall blocking outbound HTTPS; passing sampling params to a reasoning model that rejects them; SDK version mismatch after `npm install`.","solutions":["Read the inner `error.message` (already logged via console.error) — the Anthropic SDK returns a descriptive status+body; fix the root cause it names (auth, model, params).","If the model is in noTemperatureModels, ensure the request path omits temperature/top_p/top_k for that model.","Validate the key with a one-off curl: `curl https://api.anthropic.com/v1/messages -H \"x-api-key: $ANTHROPIC_API_KEY\" ...` to confirm 401 vs network.","On 429, add backoff/retry at the caller or reduce concurrency; on ECONNRESET check network/proxy/SDK version.","Rotate the key in the Anthropic dashboard and update .env if the message indicates an invalid key."],"exampleFix":"// before\nconst result = await this.anthropic.messages.create({\n  model: this.model,\n  temperature,\n  // ...\n});\n\n// after - drop sampling params for noTemperatureModels\nconst params = {\n  model: this.model,\n  ...(this.noTemperatureModels.includes(this.model)\n    ? {}\n    : { temperature }),\n};\nconst result = await this.anthropic.messages.create(params);","handlingStrategy":"try-catch","validationCode":"// Pre-flight: cheap validity checks before the paid call.\nif (!this.model) throw new Error(\"No Anthropic model selected.\");\nif (this.noTemperatureModels.includes(this.model) && temperature !== undefined) {\n  // strip sampling params to avoid a 400\n  temperature = undefined;\n}\n// (key/model reachability can only truly be tested by the call itself)","typeGuard":"/**\n * @param {unknown} e\n * @returns {boolean} e is an Anthropic SDK error with status\n */\nfunction isAnthropicSdkError(e) {\n  return (\n    e != null &&\n    typeof e === \"object\" &&\n    typeof e.message === \"string\" &&\n    (typeof e.status === \"number\" || typeof e.error === \"object\")\n  );\n}","tryCatchPattern":"try {\n  const result = await llm.getChatCompletion(messages, { temperature });\n} catch (e) {\n  const msg = e.message ?? \"\";\n  if (/401|invalid api key/i.test(msg)) await rotateKey();\n  else if (/429|rate limit/i.test(msg)) await backoffRetry(() => llm.getChatCompletion(messages, { temperature }));\n  else if (/400|temperature|top_p|top_k/i.test(msg)) stripSamplingAndRetry();\n  else throw e;\n}","preventionTips":["Map known upstream status codes (401/429/400) to specific recovery actions instead of generic rethrows.","Always log the original error object (status, headers, body) once at the boundary — not just message.","Maintain the noTemperatureModels list so reasoning models never receive sampling params.","Wrap paid calls in a timeout + bounded retry policy for transient (5xx, ECONNRESET) failures."],"tags":["network","api","anthropic","try-catch","runtime"],"backgroundTag":null,"analyzedSha":"526360e320da9d1b36074be5ed64fe76e5bbfbbd","analyzedAt":"2026-08-13T01:45:47.170Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}