Treat Anthropic APITimeoutError as retryable in the stream error classifier - #4
Open
shoemoney wants to merge 1 commit into
Open
Treat Anthropic APITimeoutError as retryable in the stream error classifier#4shoemoney wants to merge 1 commit into
shoemoney wants to merge 1 commit into
Conversation
is_retryable_anthropic_stream_error compares type(error).__name__ against a fixed name set. anthropic.APITimeoutError subclasses APIConnectionError, but the name comparison does not see subclasses, so a request timeout on the managed-agent event stream aborted the run instead of retrying. Add APITimeoutError and TimeoutError to the set, matching the name set already used by _is_retryable_openai_error in the OpenAI provider, and add a regression test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
is_retryable_anthropic_stream_error(agents/relay/providers/anthropic/events.py:162) decides retry by comparingtype(error).__name__against{"APIConnectionError", "APIStatusError"}. In the pinned anthropic SDK (0.116.0 per uv.lock),APITimeoutErrorsubclassesAPIConnectionError, so anisinstancecheck would already have treated timeouts as retryable, but the__name__equality check does not see subclasses. A timeout is also not anhttpx.TransportErrorand carries nostatus_code, so it falls through every branch and the classifier returns False. The result is that a single network timeout on the managed-agent event stream aborts the run (endpoint.py:379/396/560, files.py:123) instead of retrying, which is precisely the transient failure the retry loop exists for.Fix: add
"APITimeoutError"and"TimeoutError"to the name set, matching the set already used by_is_retryable_openai_errorin agents/relay/providers/openai/endpoint.py. Kept the name-based comparison style used by both classifiers rather than switching to isinstance.Test: added agents/relay/providers/anthropic/test_events_retry.py. Constructing
anthropic.APITimeoutError(request=...)against the locked SDK, the classifier returned False before this change and True after; non-retryable errors (400) still return False. Verified withuv sync --locked;ruff checkper .github/workflows/checks.yml passes.