Repository navigation
fix(sdk): retry ProcessError exit-143 (gateway stream-drop) instead of failing permanently - #316
Open
mtoslalibu wants to merge 1 commit into
Open
mtoslalibu wants to merge 1 commit into
mtoslalibu wants to merge 1 commit into
Conversation
…f failing permanently When the gateway drops a long streaming response, the Agent SDK SIGTERMs its claude child, surfacing as ProcessError "(exit code: 143)" / "Fatal error in message reader". The runner's classifier only matched transport error names (ConnectionError/TimeoutError/...), so this transient infra fault was re-raised as permanent and aborted the whole iteration with no retry. Extract the transient-vs-permanent classifier into a pure, unit-tested helper `_is_transient_sdk_error`. Classify ProcessError by its structured exit_code: only 143 (the SIGTERM) is transient; every other non-zero exit (bad request, usage, config) stays permanent and fails fast. A message-text fallback (exit-code-143-specific) covers the wrapped-in-ExceptionGroup case. Retry stays bounded by --max-cli-retries and logged to retry_log.jsonl. Refs #315 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Collaborator
Author
|
@claude please review this PR. Focus on: (1) the ProcessError exit-143 classification correctness (false-positive/over-broad-catch risk — should only exit_code==143 be retried?), (2) that the refactor preserves the original transient-signal behavior exactly, (3) test coverage of the retry path, and (4) adherence to the repo's no-live-LLM-calls test policy. |
Collaborator
Author
|
@claude please review this PR (re-triggering — runner was wedged). Focus: ProcessError exit-143 classification correctness, refactor preserves original transient behavior, retry-path test coverage, and no-live-LLM test policy. |
sriumcp
added a commit
to sriumcp/agentic-strategy-evolution
that referenced
this pull request
Oct 17, 2026
sriumcp
added a commit
to sriumcp/agentic-strategy-evolution
that referenced
this pull request
Oct 17, 2026
…ystems-Research#316 exit-143, AI-native-Systems-Research#303 reaping + wall clock, AI-native-Systems-Research#264/AI-native-Systems-Research#281 regression + resume override, AI-native-Systems-Research#304 report routing) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
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.
Closes #315
Problem
When the LLM gateway drops a long streaming response mid-turn, the Claude Agent SDK's reader errors and SIGTERMs its
claudechild, surfacing asProcessError"(exit code: 143)" / "Fatal error in message reader". The SDK runner's classifier only matched transport error class-names (ConnectionError,TimeoutError, …), so this transient infra fault was re-raised as permanent and aborted the whole campaign iteration — the bounded retry machinery (--max-cli-retries,retry_log.jsonl) never engaged. Observed repeatedly on long Opus DESIGN turns via a litellm→Bedrock proxy; the same campaign/config completes fine when the gateway is healthy, confirming it's transient.Fix
_is_transient_sdk_error(exc)(no behaviour change for the existing 6 transport signals).ProcessErrorby its structuredexit_code: only 143 (the SIGTERM) is transient; every other non-zero exit (bad request, usage, config — exit 1/2/…) stays permanent and fails fast, so deterministic failures don't burn 10 retries.ExceptionGroupcase (a bare "message reader" banner is intentionally excluded so a wrapped non-143 error can't be mis-retried).--max-cli-retriesand every attempt is logged toretry_log.jsonl; the original error is preserved viaraise ... from exc.Tests
New
TestSDKTransientClassification(7 cases, offline, no live LLM calls per repo policy):ProcessError(exit_code=143)transient (fake + real-SDK);ProcessError(exit_code=1/2/None)permanent (fake + real-SDK) — the regression surface;Full suite: 1357 passed, 2 skipped.
Reviewed
Self-reviewed with the PR-review toolkit (code-reviewer + silent-failure-hunter); the key must-fix (don't retry non-143 non-zero exits) and the fallback-breadth edge case were caught and addressed in review rounds before this PR.