Compare commits

...

3 Commits

Author SHA1 Message Date
Vincent Koc
b2ae58a348 chore(changelog): add anthropic failover entry 2026-03-30 12:49:41 +09:00
Vincent Koc
ae3bbc430b Merge branch 'main' into fix/api-error-unexpected-transient 2026-03-29 20:49:12 -07:00
zijiess
169d5f9e7e fix(agents): classify Anthropic "unexpected error" api_error as transient (#57010)
Anthropic sometimes returns api_error payloads with message "An unexpected
error occurred while processing the response" during mid-stream failures.
This was not matched by API_ERROR_TRANSIENT_SIGNALS_RE, causing the error
to surface as terminal instead of triggering retry/fallback.

Add "unexpected error" to the transient signal regex. This follows the
same pattern as prior fixes for "Internal server error" (#23193) and
overloaded_error 529 (#34535).

Closes #57010
2026-03-30 11:21:37 +08:00
3 changed files with 8 additions and 1 deletions

View File

@@ -86,6 +86,7 @@ Docs: https://docs.openclaw.ai
- Cron/announce: preserve all deliverable text payloads for announce mode instead of collapsing to the last chunk, so multi-line cron reports deliver in full to Telegram forum topics.
- Harden async approval followup delivery in webchat-only sessions (#57359) Thanks @joshavant.
- Status: fix cache hit rate exceeding 100% by deriving denominator from prompt-side token fields instead of potentially undersized totalTokens. Fixes #26643.
- Agents/Anthropic failover: treat Anthropic `api_error` payloads with `An unexpected error occurred while processing the response` as transient so retry/fallback can engage instead of surfacing a terminal failure. (#57441) Thanks @zijiess and @vincentkoc.
## 2026.3.28

View File

@@ -916,6 +916,12 @@ describe("classifyFailoverReason", () => {
'{"type":"error","error":{"type":"api_error","message":"Service temporarily unavailable"}}',
),
).toBe("timeout");
// Anthropic "unexpected error" variant (#57010)
expect(
classifyFailoverReason(
'{"type":"error","error":{"type":"api_error","message":"An unexpected error occurred while processing the response"}}',
),
).toBe("timeout");
});
it("does not classify non-transient api_error payloads as timeout", () => {
// Context overflow - not transient

View File

@@ -859,7 +859,7 @@ export function isBillingAssistantError(msg: AssistantMessage | undefined): bool
// Non-transient api_error payloads (context overflow, validation/schema errors)
// must NOT be classified as timeout.
const API_ERROR_TRANSIENT_SIGNALS_RE =
/internal server error|overload|temporarily unavailable|service unavailable|unknown error|server error|bad gateway|gateway timeout|upstream error|backend error|try again later|temporarily.+unable/i;
/internal server error|overload|temporarily unavailable|service unavailable|unknown error|server error|bad gateway|gateway timeout|upstream error|backend error|try again later|temporarily.+unable|unexpected error/i;
function isJsonApiInternalServerError(raw: string): boolean {
if (!raw) {