Session becomes permanently unrecoverable after streaming errors due to retry message accumulation
Bug Description
When a streaming connection drops mid-response (e.g., due to network instability), Claude Code's retry mechanism appends new messages to the conversation on each retry attempt. This causes the session payload to grow monotonically, eventually making the session permanently unrecoverable — even across restarts with --resume.
This is not a network issue. Other sessions created at the same time, on the same machine, with the same network, work perfectly. The problem is Claude Code's internal retry behavior corrupting the session state.
Root Cause
From debug logs (~/.claude/debug/), the message count increments with every failed retry:
Messages deferred by 1 (510→511) # retry 1
Messages deferred by 1 (511→512) # retry 2
Messages deferred by 1 (512→513) # retry 3
Messages deferred by 1 (513→514) # retry 4
Messages deferred by 1 (514→515) # retry 5
Messages deferred by 1 (515→516) # retry 6
Messages deferred by 1 (516→517) # retry 7
Each retry adds a message to the session, inflating the API request payload. Since the full conversation history is sent with each request, the payload grows larger with every failed attempt, making subsequent retries more likely to fail — a positive feedback loop.
Reproduction Steps
- Use Claude Code with a moderately long session (~500 messages, ~100K tokens)
- Experience a network interruption during streaming (e.g., proxy timeout, socket close)
- Observe Claude Code retrying up to 11 times, each time incrementing the message count
- The session becomes permanently broken —
--resumereloads the bloated state and fails the same way - Meanwhile, starting a new session on the same machine works fine
Debug Log Evidence
17:08:36 [ERROR] Error streaming, falling back to non-streaming mode: The socket connection was closed unexpectedly.
17:09:45 [ERROR] Error streaming, falling back to non-streaming mode: The socket connection was closed unexpectedly.
17:10:17 [ERROR] API error (attempt 1/11): undefined Connection error.
17:10:50 [ERROR] API error (attempt 2/11): undefined Connection error.
17:11:22 [ERROR] API error (attempt 3/11): undefined Connection error.
17:11:58 [ERROR] API error (attempt 4/11): undefined Connection error.
17:12:35 [ERROR] API error (attempt 5/11): undefined Connection error.
17:13:16 [ERROR] API error (attempt 6/11): undefined Connection error.
17:14:05 [ERROR] API error (attempt 7/11): undefined Connection error.
Note: OAuth auth succeeds every time, and the stream initially starts successfully — the connection drops mid-transfer. This confirms the API server is reachable; the issue is with how Claude Code handles the failure.
Expected Behavior
- Retries should not increment the message count — failed attempts should not modify the conversation state
- After N consecutive failures, Claude Code should attempt auto-compaction to reduce payload size
- A session that was working before a transient error should be recoverable after the network stabilizes
Actual Behavior
- Each retry appends a message, growing the payload
- The session enters an unrecoverable state (snowball effect)
--resumereplays the bloated state, immediately hitting the same issue- Only workaround is to abandon the session entirely
Environment
- Claude Code v2.1.86
- macOS (Apple Silicon)
- Runtime: Bun
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗