[BUG] Session forking (backgrounding/resume) has no parent-child linkage — compounds into unbounded duplicate-named entries for recurring jobs
Summary
Backgrounding a session, resuming from Agent View, or /resume in general all fork a new session ID that continues the conversation — but none of these surface any link back to the session they forked from. For a one-off fork this shows up as mild confusion (which of these two identically-named entries is current?). For a named background job that gets restarted/resumed repeatedly, it compounds into an unbounded, ever-growing list of same-named, unlinked entries with no way to tell which is live.
Evidence
Confirmed directly in local session transcripts: forking writes "Backgrounding after the current tool finishes…" as the terminal entry of the parent session, then the child session's first records (ai-title, agent-name) carry the identical display name forward with no reference to the parent session ID. One recurring named job in my own history has forked across 5+ session IDs over ~2.5 months, all showing identically in the session list.
Related issues (likely same root cause, different symptoms)
- #78264 —
/resumeforks duplicate custom titles onto new session IDs - #70373 — backgrounding with in-flight subagents forks and orphans the original
- #83971 — backgrounding seeds the new job with only the last prompt, dropping prior context
- #76493 — resuming from Agent View forks (new id), freezes the original, empties the task list
Suggested fix
Either (a) collapse fork chains into a single thread in the session list with the ability to expand history, or (b) at minimum surface a "continued from" / "continues to" link between parent and child sessions so stale forks are identifiable and the relationship is discoverable.
Impact
Session list becomes unbounded clutter for any workflow that relies on repeatedly backgrounding/resuming the same logical task — which is exactly the pattern background jobs and named recurring tasks are meant to support.
3 Comments
Independent confirmation of this, with the structural evidence for the parent-child link and a
version data point that may help bisect it.
Same terminal entry, and the child's first record shares the parent's
parentUuid. On2026-08-05 under 2.1.222, a session backgrounded while a long foreground
Bashcall was inflight (no subagents involved):
| time (UTC) | session | event |
|---|---|---|
| 17:12:09 |
d9dc26b3| assistant issues aBashcall expected to run ~8 minutes || 17:18:14 |
d9dc26b3| system record,level: warning:"Backgrounding after the current tool finishes…"— Ctrl-B || 17:18:32 |
4092f917| new session id re-issues the same command (identical but for ahead -20) |The two transcripts share an identical 212-record prefix, and the first divergent record on each
side has the same
parentUuid. So the lineage does exist in the data — two children of oneparent record — it is simply never surfaced. That may be an easier hook for the fix than titles:
the child's first divergent record already points at the parent.
Possible fix already landed, worth checking before you dig. Under 2.1.227 I backgrounded a
long foreground
Bashcall the same way and it did not fork: the conversation continued in thesame session id, a task id was returned, and no new transcript file appeared. Related #70373 was
filed against 2.1.186 and last updated Aug 7, so nobody there has noted this. If the fork is fixed,
the linkage gap described in this issue still stands for every already-forked session in
~/.claude/projects— mine still lists a dead branch and its live continuation as peers.What the missing linkage actually costs, beyond duplicate names.
claude -roffered threeentries for one directory; two were this fork pair (one abandoned Aug 5, one active through Aug 8).
I picked the first and got the dead branch. That silently reinstated a four-day-old view of the
working tree: the resumed context described work as unimplemented that the live branch had since
committed. The assistant continued on that basis and re-derived work that already existed, reporting
it as newly done, until we audited file mtimes,
git log, and the transcripts — about an hour lost,and several confidently wrong status reports along the way.
That last part is why I'd argue ordering matters as much as linkage. Concretely, in priority order:
signal most users will act on.
One data point that contradicts a related issue: #82489 reports the child session having no
transcript. Here the child had the parent's prefix duplicated in full (consistent with #85179's
"forks duplicate ~90% of content"). Same trigger, opposite symptom — possibly two distinct paths
worth separating during triage.
Environment: Linux,
entrypoint: cli, versions 2.1.222 (forked) and 2.1.227 (did not fork). Happyto provide redacted transcript excerpts; the files themselves contain proprietary source.
Corroborating data point, macOS, VS Code terminal, reported from 2.1.235. Adds a detail beyond ambiguity: the picker's timestamp is actively wrong for the stale fork.
Fork observed in transcripts:
2026-08-18T07:55:31Z.isCompactSummary, followed by 749 message uuids shared with the parent; new turns begin at line 791. Last message2026-08-18T18:47:23Z.customTitleverbatim. Both rows render identically.New symptom:
/resumelabels rows by file mtime, and the parent's mtime is2026-08-18T19:07Z— 11h11m after its last message. The parent's final 6 lines are timestamp-less metadata records (agent-name,mode,permission-mode,pr-link,last-prompt), so metadata appends bump mtime with no conversation activity. Result: parent and child both displayed "9 hours ago" despite an 11h gap in actual last message. The only distinguishing field left is file size, which does not indicate recency — the parent is 22.5MB and stale, the child 5.1MB and current.Consequence beyond clutter: resuming the parent branches a third file from a point 11h stale, silently stranding the child's work. A user picking by displayed time has no signal that distinguishes them.
Constraint any fix must satisfy: the row's timestamp needs to come from the last conversation message, not file mtime — otherwise parent/child linkage alone still leaves two rows claiming the same recency.
session forking with no parent-child linkage turns recurring jobs into duplicate-named clones.
treat "ping failed" as retry-message, not spawn-another, until a real liveness check says dead.