Session becomes permanently unrecoverable after streaming errors due to retry message accumulation

Resolved 💬 5 comments Opened Mar 28, 2026 by ljxrrcj Closed Apr 30, 2026

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

  1. Use Claude Code with a moderately long session (~500 messages, ~100K tokens)
  2. Experience a network interruption during streaming (e.g., proxy timeout, socket close)
  3. Observe Claude Code retrying up to 11 times, each time incrementing the message count
  4. The session becomes permanently broken — --resume reloads the bloated state and fails the same way
  5. 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)
  • --resume replays 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

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗