thedotmack/claude-mem · error · ServerClassifiedProviderError

Anthropic API error

Error message

Anthropic API error: ${response.status} - ${bodyText}

What it means

Anthropic returned a non-2xx HTTP status to the ClaudeObservationProvider. The provider reads the response body and passes status, body text, and headers to classifyClaudeServerError, attaching cause `Anthropic API error: <status> - <body>`. The classifier maps statuses (401 invalid key, 429 rate limit, 5xx/overloaded retryable, 4xx unrecoverable) onto a ServerClassifiedProviderError.

Solutions

  1. Read the classified error kind: retryable (429/5xx/529) → retry with the retryAfter delay; unrecoverable → fix the request or credentials.
  2. Verify the API key and account billing/status in the Anthropic console.
  3. Check the model identifier is valid and enabled for your account.
  4. Respect the Retry-After header on 429/overloaded responses.

Example fix

// before
throw new Error('claude failed');
// after
if (err.kind === 'retryable') return retryWithBackoff(call, err.retryAfterMs);
logger.error(`Anthropic unrecoverable: ${err.cause?.message}`);
Defensive patterns

Strategy: retry

Validate before calling

if (!process.env.ANTHROPIC_API_KEY) throw new Error('ANTHROPIC_API_KEY not set');
// and validate the model id against the account's allowed list before calling

Type guard

function isRetryableProviderError(e: unknown): boolean {
  return typeof e === 'object' && e !== null && 'kind' in e && (e as {kind: string}).kind === 'retryable';
}

Try / catch

try {
  result = await provider.generate(prompt, signal);
} catch (e) {
  if (e.kind === 'retryable' && e.retryAfterMs) return sleep(e.retryAfterMs).then(call);
  throw e;
}

Prevention

When it happens

Trigger: `postMessages()` resolves but `response.ok` is false: 401/403 bad API key, 429 rate-limited, 400 invalid request/model name, 500/529 Anthropic outage — thrown at ClaudeObservationProvider.ts:82-89.

Common situations: Expired or wrong ANTHROPIC_API_KEY, hitting org rate limits during parallel generation, deprecated model ID sent to the API, Anthropic overloaded (529) during traffic spikes, billing issues.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/1ed14e8e93702c55. Report an issue: GitHub.

Appendix: source

Thrown at src/server/generation/providers/ClaudeObservationProvider.ts:85

        rawText: '<skip_summary reason="all_events_private" />',
        providerLabel: this.providerLabel,
        modelId: this.model,
      };
    }

    let response: Response;
    try {
      response = await this.postMessages(prompt, signal);
    } catch (networkError) {
      const err = networkError instanceof Error ? networkError : new Error(String(networkError));
      throw classifyClaudeServerError({
        cause: err,
      });
    }

    if (!response.ok) {
      const bodyText = await safeReadBody(response);
      throw classifyClaudeServerError({
        status: response.status,
        bodyText,
        headers: response.headers,
        cause: new Error(`Anthropic API error: ${response.status} - ${bodyText}`),
      });
    }

    let data: AnthropicMessagesResponse;
    try {
      data = (await response.json()) as AnthropicMessagesResponse;
    } catch (parseError) {
      const err = parseError instanceof Error ? parseError : new Error(String(parseError));
      throw new ServerClassifiedProviderError('Anthropic returned invalid JSON', {
        kind: 'parse_error',
        cause: err,
      });
    }

View on GitHub (pinned to d8bc9755e7)