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
- Read the classified error kind: retryable (429/5xx/529) → retry with the retryAfter delay; unrecoverable → fix the request or credentials.
- Verify the API key and account billing/status in the Anthropic console.
- Check the model identifier is valid and enabled for your account.
- 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
- Validate API key and billing status before deploying.
- Throttle parallel generation to stay under org rate limits.
- Pin and verify model IDs against current Anthropic model names.
- Honor Retry-After headers; use exponential backoff with jitter.
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
- OpenRouter API error
- Anthropic API error
- Gemini HTTP error (status )
- Aborting session for quota guard
- Anthropic API rejected request with HTTP 400: this model…
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)