You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a background fork of a session is running (--session-id <fork-id> --fork-session --resume <parent-transcript>), it inherits the parent session's custom title. If the parent is also alive as a named agent, claude agents --json correctly lists both sessions (same name, different sessionId), but the interactive claude agents view renders only one row for that name. Attaching via that row reaches the parent; the fork is unreachable from the picker.
Meanwhile, claude --resume <fork-id> refuses with:
Session <fork-id> is currently running as a background agent (bg). Use `claude agents` to find and attach to it, or add --fork-session to branch off a copy.
…which is circular: the command it points to cannot surface the session. The only options left are --fork-session (a divergent copy of a session that is itself still running, inviting three-way divergence) or waiting for the bg agent to finish. Related but distinct from #70170, which asks for a takeover path in --resume; this report is about the agent view making the recommended path a dead end.
Environment
Claude Code: 2.1.198
OS: macOS (Darwin 25.5.0), Apple Silicon
Reproduction
Run an interactive named session in a project dir: claude --name myproject@mytask → session <parent-id>.
A background fork of it is spawned via the daemon (observed process):
claude --session-id <fork-id> --fork-session --resume ~/.claude/projects/<project>/<parent-id>.jsonl --reply-on-resume ...
hosted under claude --bg-pty-host /tmp/cc-daemon-<uid>/<hash>/pty/<fork-id-prefix>.sock ...
The fork's transcript begins with the inherited title, so both sessions share a display name:
The claude agents TUI shows a single myproject@mytask row in Working. Selecting it attaches to the parent. There is no row for <fork-id>.
claude --resume <fork-id> → the refusal quoted above, pointing back to the picker that can't show it.
The fork is healthy the whole time (its pty host and worker process are alive and mid-task); this is purely a discoverability/attach problem.
Expected
One row per live session in the agent view, even when names collide — disambiguate with a session-id prefix, a (fork) marker, or the fork's own recent activity line.
Correction / sharper diagnosis (after further investigation)
Step 5 above was wrong in one detail: the single TUI row attaches to the fork (the live session), not the parent. The full picture turned out to be:
The daemon rotates a named agent's session ID: when a new prompt reached the named agent, the conversation continued as a brand-new session (--session-id <fork-id> --fork-session --resume <parent>.jsonl --reply-on-resume). The parent transcript froze at that moment, but claude agents --jsonstill reports the parent as status: "busy" alongside the live fork — two same-named entries, one of them a stale claim.
The user, holding a session ID copied from a path, ran claude --resume <fork-id> and got the bg-agent refusal — with no hint that this ID was the live continuation of the very chat already open in their terminal under the agent's name.
Extra trap: paths like <session-dir>/tasks/<task-name>.output look session-addressable but are subagent outputs (symlinks to <session-dir>/subagents/agent-<task-name>.jsonl). Subagents have no top-level session ID, so no --resume incantation can ever reach them; nothing in the CLI says so.
So the actionable asks refine to:
Surface both same-named sessions distinctly in the TUI, and mark stale/frozen claims (parent hadn't written its transcript for 40+ minutes yet showed busy).
When --resume <id> hits a live bg session, say where it's attached (e.g. "currently attached in agent view as <name>") instead of only refusing.
When a user tries to resume something under a session's subagents//tasks/ dir, explain that subagents aren't resumable sessions and point at the parent session ID.
Summary
When a background fork of a session is running (
--session-id <fork-id> --fork-session --resume <parent-transcript>), it inherits the parent session's custom title. If the parent is also alive as a named agent,claude agents --jsoncorrectly lists both sessions (samename, differentsessionId), but the interactiveclaude agentsview renders only one row for that name. Attaching via that row reaches the parent; the fork is unreachable from the picker.Meanwhile,
claude --resume <fork-id>refuses with:…which is circular: the command it points to cannot surface the session. The only options left are
--fork-session(a divergent copy of a session that is itself still running, inviting three-way divergence) or waiting for the bg agent to finish. Related but distinct from #70170, which asks for a takeover path in--resume; this report is about the agent view making the recommended path a dead end.Environment
Reproduction
claude --name myproject@mytask→ session<parent-id>.claude --bg-pty-host /tmp/cc-daemon-<uid>/<hash>/pty/<fork-id-prefix>.sock ...{"type":"custom-title","customTitle":"myproject@mytask","sessionId":"<fork-id>"}claude agents --jsonlists both (anonymized):{"sessionId":"<parent-id>","name":"myproject@mytask","status":"busy","state":null} {"sessionId":"<fork-id>","name":"myproject@mytask","status":"busy","state":"working"}claude agentsTUI shows a singlemyproject@mytaskrow in Working. Selecting it attaches to the parent. There is no row for<fork-id>.claude --resume <fork-id>→ the refusal quoted above, pointing back to the picker that can't show it.The fork is healthy the whole time (its pty host and worker process are alive and mid-task); this is purely a discoverability/attach problem.
Expected
(fork)marker, or the fork's own recent activity line.--resumerefusal should include enough identity to act on (name + how many sessions share it), and ideally an attach-by-id path (claude agents --select <session-id>, cf. Feature request: programmatically focus/attach a session in the agents view (e.g.claude agents --select <session-id>) #68064) so the message's advice is actionable from a script or when names collide.Notes
titleisnullfor every entry inclaude agents --jsoneven when a custom title exists in the transcript — same observation as Cannot resume a session held as a background agent:--resume <id>refuses with no takeover/reclaim path #70170; populating it would make--jsonusable for disambiguation.Correction / sharper diagnosis (after further investigation)
Step 5 above was wrong in one detail: the single TUI row attaches to the fork (the live session), not the parent. The full picture turned out to be:
--session-id <fork-id> --fork-session --resume <parent>.jsonl --reply-on-resume). The parent transcript froze at that moment, butclaude agents --jsonstill reports the parent asstatus: "busy"alongside the live fork — two same-named entries, one of them a stale claim.claude --resume <fork-id>and got the bg-agent refusal — with no hint that this ID was the live continuation of the very chat already open in their terminal under the agent's name.<session-dir>/tasks/<task-name>.outputlook session-addressable but are subagent outputs (symlinks to<session-dir>/subagents/agent-<task-name>.jsonl). Subagents have no top-level session ID, so no--resumeincantation can ever reach them; nothing in the CLI says so.So the actionable asks refine to:
busy).--resume <id>hits a live bg session, say where it's attached (e.g. "currently attached in agent view as<name>") instead of only refusing.subagents//tasks/dir, explain that subagents aren't resumable sessions and point at the parent session ID.