Failed requests fork a new conversation branch per retry, leaving dead tips in the transcript

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 0 comments · opened Jul 27, 2026

What happened

When an API request fails mid-session, Claude Code appends the retry as a new sibling branch off the same parent node rather than retrying in place. Each subsequent retry forks again, so a session that fails repeatedly accumulates many dead branches.

During a period of repeated ECONNRESET failures I ended up with sessions containing 8, 10, 12, 13, and in one case 20 leaf tips, where a healthy session has 1.

Why it matters

  1. It looks like transcript corruption but isn't. I audited the affected .jsonl files: every line was valid JSON, every tool_use had a matching tool_result, there were no duplicate UUIDs and no dangling parentUuid pointers. The files were structurally perfect. The only anomaly was the branch fan-out, which made them appear damaged and sent me down a long debugging path.
  1. It compounds the original failure. Each fork appends more records to a file that is already too large to send, so every retry makes the next attempt marginally worse.
  1. --resume can land on a dead branch. In one session the recorded resume leaf pointed at a system/local_command record for a cancelled resume, i.e. the tail of a branch that had never succeeded.

Reproduction

  1. Grow a session large enough that requests start failing (or otherwise induce a transport failure).
  2. Retry a few times from the same point.
  3. Inspect the session .jsonl: group records by parentUuid and count nodes with no message-type descendants.

Each retry adds a leaf rather than replacing one.

Note on scope

This is not universal. Some sessions that failed several times retried linearly and still show a single tip, so the forking appears conditional — possibly on whether the failure occurs before or after the user message is committed. I did not isolate the trigger.

Expected

A failed request should retry in place, or the dead branch should be pruned, so the transcript keeps one live tip.

Environment

  • Claude Code 2.1.220
  • macOS (darwin 25.1.0)
  • Model: Opus, 1M context

View original on GitHub ↗