Summary
AnthropicAdapter.handleError at src/providers/anthropic.ts:350-351 classifies any error containing "context" or "too long" in its message as a non-retryable context_length error, regardless of HTTP status:
```ts
if (message.includes('context') || message.includes('too long')) {
return contextLengthError(message, error, rawRequest);
}
```
A 5xx response whose body happens to contain those substrings — e.g. \"Internal error: context processing failed\", \"Backend took too long to respond\" — is misclassified as context_length instead of server, which silently suppresses correct retry behavior. The user's request fails permanently on a transient backend error.
The newly-added 400-classification branch this PR (#16) introduced sits structurally adjacent to this heuristic, making it a natural fix-together. Greptile rated this P1 on PR #16's review thread; the PR merged with no author reply and the guard wasn't added.
Suggested fix
Gate the heuristic on status === 400 (and possibly the explicit context_length error code if Anthropic surfaces one):
```ts
if (status === 400 && (message.includes('context') || message.includes('too long'))) {
return contextLengthError(message, error, rawRequest);
}
```
A 4xx-only classifier matches the real failure mode: context-length is a client-side request shape problem, never something a 5xx can signal.
Code
src/providers/anthropic.ts:335 — handleError signature
src/providers/anthropic.ts:350-351 — the unguarded heuristic
src/providers/anthropic.ts:74, 245 — both handleError call sites (request + stream paths)
Severity
High — silently suppresses retries on transient backend failures whose error text happens to contain a common English word. Fresh merge (PR #16 landed 2026-05-21) so impact in production is currently bounded, but every retried request taking this path will fail incorrectly.
Origin
Greptile P1 finding on PR #16 (merged 2026-05-21). Not addressed in merge.
Summary
AnthropicAdapter.handleErroratsrc/providers/anthropic.ts:350-351classifies any error containing "context" or "too long" in its message as a non-retryablecontext_lengtherror, regardless of HTTP status:```ts
if (message.includes('context') || message.includes('too long')) {
return contextLengthError(message, error, rawRequest);
}
```
A 5xx response whose body happens to contain those substrings — e.g.
\"Internal error: context processing failed\",\"Backend took too long to respond\"— is misclassified ascontext_lengthinstead ofserver, which silently suppresses correct retry behavior. The user's request fails permanently on a transient backend error.The newly-added 400-classification branch this PR (#16) introduced sits structurally adjacent to this heuristic, making it a natural fix-together. Greptile rated this P1 on PR #16's review thread; the PR merged with no author reply and the guard wasn't added.
Suggested fix
Gate the heuristic on
status === 400(and possibly the explicitcontext_lengtherror code if Anthropic surfaces one):```ts
if (status === 400 && (message.includes('context') || message.includes('too long'))) {
return contextLengthError(message, error, rawRequest);
}
```
A 4xx-only classifier matches the real failure mode: context-length is a client-side request shape problem, never something a 5xx can signal.
Code
src/providers/anthropic.ts:335—handleErrorsignaturesrc/providers/anthropic.ts:350-351— the unguarded heuristicsrc/providers/anthropic.ts:74, 245— bothhandleErrorcall sites (request + stream paths)Severity
High — silently suppresses retries on transient backend failures whose error text happens to contain a common English word. Fresh merge (PR #16 landed 2026-05-21) so impact in production is currently bounded, but every retried request taking this path will fail incorrectly.
Origin
Greptile P1 finding on PR #16 (merged 2026-05-21). Not addressed in merge.