{"record":{"id":"29b2262ce9ca9afd","repo":"linshenkx/prompt-optimizer","slug":"anthropic-api-error-error-status-error-mes","errorCode":null,"errorMessage":"Anthropic API error (${error.status}): ${error.message}","messagePattern":"Anthropic API error \\((.+?)\\): (.+?)","errorType":"exception","errorClass":"APIError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/llm/adapters/anthropic-adapter.ts","lineNumber":152,"sourceCode":"        console.log(`[AnthropicAdapter] Successfully fetched ${models.length} models`)\n        return models\n      }\n\n      throw new APIError('Unexpected API response format')\n    } catch (error: any) {\n      console.error('[AnthropicAdapter] Failed to fetch models:', error)\n\n      // 连接错误处理（包括跨域检测）\n      if (error.message && (error.message.includes('Failed to fetch') ||\n          error.message.includes('NetworkError') ||\n          error.message.includes('ECONNREFUSED') ||\n          error.message.includes('CORS'))) {\n        throw new APIError(`Network error: ${error.message}`)\n      }\n\n      // API 错误处理\n      if (error.status) {\n        throw new APIError(`Anthropic API error (${error.status}): ${error.message}`)\n      }\n\n      // 其他错误\n      throw error\n    }\n  }\n\n  // ===== 参数定义（用于buildDefaultModel） =====\n\n  /**\n   * 获取参数定义\n   */\n  protected getParameterDefinitions(modelId: string): readonly ParameterDefinition[] {\n    const samplingDefinitions: ParameterDefinition[] = [\n      {\n        name: 'temperature',\n        labelKey: 'params.temperature.label',\n        descriptionKey: 'params.temperature.description',","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/llm/adapters/anthropic-adapter.ts#L134-L170","documentation":"Anthropic's API returned a non-2xx status; the caught error has a numeric status property and the adapter formats it as 'Anthropic API error (status): message'. This maps directly to Anthropic's documented HTTP error codes (401 invalid key, 403 blocked region, 429 rate limit, 5xx server errors).","triggerScenarios":"getModelsAsync() with an invalid/expired x-api-key (401), hitting rate limits (429), region-blocked access (403), or an Anthropic outage (5xx).","commonSituations":"Revoked API key, wrong key environment variable, free-tier rate limiting, calling from a blocked geography without a proxy.","solutions":["Check the status number in the message: 401/403 → rotate/reissue the API key and verify key permissions","429 → add backoff/retry and reduce request frequency","5xx → check status.anthropic.com and retry with exponential backoff","Confirm the key is passed via connectionConfig.apiKey and matches the account/environment"],"exampleFix":"// before\nconst models = await adapter.getModelsAsync()\n\n// after\ntry {\n  const models = await adapter.getModelsAsync()\n} catch (e: any) {\n  const m = /Anthropic API error \\((\\d+)\\)/.exec(e.message)\n  if (m && Number(m[1]) === 429) return backoffRetry(() => adapter.getModelsAsync())\n  throw e\n}","handlingStrategy":"retry","validationCode":"null","typeGuard":"function isAnthropicHttpError(e: unknown): e is APIError & { status?: number } {\n  return e instanceof APIError && /Anthropic API error \\(\\d+\\)/.test(e.message)\n}","tryCatchPattern":"try { await adapter.getModelsAsync() }\ncatch (e) {\n  if (isAnthropicHttpError(e)) {\n    const status = Number(/\\((\\d+)\\)/.exec(e.message)![1])\n    if (status === 429 || status >= 500) return backoffRetry(() => adapter.getModelsAsync())\n  }\n  throw e\n}","preventionTips":["Validate API keys before first use","Implement 429-aware exponential backoff globally","Monitor Anthropic status page for 5xx clusters"],"tags":["anthropic","http-status","api-key","rate-limit"],"backgroundTag":"llm-api-http-error","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}