Workflows/agents view hydration relaunch can attach the TUI to a stale session under tmux; agent-name/ai-title stamped onto unrelated sessions
Environment
- Claude Code v2.1.201 (native installer,
~/.local/share/claude/versions/2.1.201) - macOS Darwin 25.5.0 (Apple Silicon)
- tmux 3.7 (claude launched as the tmux pane command, one session per terminal tab)
- Shared per-user daemon active (
claude daemon run), background/fleet features enabled
Summary
Opening the workflow/agents view (/workflows) triggers a one-time TUI self-relaunch to hydrate the fleet-gated UI. The relaunched instance re-resolves which session it belongs to — and when claude runs inside tmux (where pane ttys and pane ids are recycled rapidly across short-lived sessions), that resolution can land on a stale, settled session from a different window. The user-visible effect: the live conversation is replaced by the welcome splash, MCP servers restart, and the tab comes back attached to an old session. The stale session's transcript receives new writes.
A second, likely-related bug: the daemon's naming flow stamps ai-title / agent-name entries onto unrelated sessions that have no name yet.
What happened (production observation)
- Session A (project X) ran a dynamic-workflow-heavy task inside a tmux pane; it settled: daemon log
bg settled 1eb3e5bd (done). - Later, a fresh session B was launched in a different directory (project Y), also in a tmux pane, and the workflow view was opened.
- Daemon log at that moment:
````
[...] [bg] bg claimed-spare ca4bf33f (spare)
[...] [bg] bg spawned a1591ab7 (slash)
[...] [bg] bg claimed-spare 1eb3e5bd (fleet) <-- the SETTLED session A resumed for "fleet"
- Session A's transcript (
1eb3e5bd-….jsonl) received newattachment/systementries minutes after it had settled. - Session B's tab ended up showing/attached to the stale session A content instead of its own conversation. The original TUI process never exited (same pid, same start time) — this is a TUI/identity-level swap, not a crash.
Related naming bug (same identity-confusion family)
When session A's agent name was generated (rust-terminal-rendering-recon), the same {"type":"ai-title"...} + {"type":"agent-name"...} entries were also appended to other sessions that had no name yet — each stamped with the receiving session's own sessionId:
- a brand-new session in another project dir (transcript contained ONLY those two entries, zero conversation),
- an hours-old idle scratch session (entries appended long after it went idle).
Sessions that already had their own ai-title were untouched. Diagnostic used:
grep -o '"type":"ai-title"[^}]*\|"type":"agent-name"[^}]*' <transcript>.jsonl | sort | uniq -c
The "donor" session had 863 stamps of its own name; the two victims had 1–2 foreign stamps each.
Reproduction (scripted, isolated tmux socket)
W=/tmp/avr; mkdir -p "$W" /tmp/avrepro
TMUX_TMPDIR=$W tmux new-session -d -x 100 -y 30 -s repro -c /tmp/avrepro claude
# accept folder trust, wait for composer, then:
TMUX_TMPDIR=$W tmux send-keys -t repro "/workflows"; sleep 1
TMUX_TMPDIR=$W tmux send-keys -t repro Enter; sleep 5
TMUX_TMPDIR=$W tmux capture-pane -t repro -p
Observed on first /workflows in a session: the full TUI re-renders from the welcome splash, MCP servers are torn down and restarted (⚠ N MCP servers need authentication · run /mcp appears), then the "Dynamic workflows" panel opens. Subsequent open/close round-trips in the same TUI preserve the conversation — the damage window is the one-time hydration relaunch, when competing session identities exist (which tmux makes far more likely by recycling ttys/pane ids).
Mechanism notes (from the shipped binary)
- The hydration handoff passes state via env:
CLAUDE_CODE_AGENT_VIEW_RELAUNCH(AGENT_VIEW_RELAUNCH_ENV_KEY), consumed at startup byconsumeAgentViewRelaunchMarker()(reads env, deletes it, returns parsed marker), with session start typeagents_view. - The stale attach correlates with the daemon resuming a settled session for the fleet view (
bg claimed-spare <id> (fleet)).
Mitigation that works (suggests the fix)
Launching with an explicit --session-id <uuid> makes the post-relaunch resolution unambiguous: a pinned session survives the /workflows round-trip with its conversation intact, transcript stays at the pinned id, no stray sessions are created (verified via the scripted repro). Suggests the relaunch/resume path should always prefer an explicit inherited session identity over tty/pane-keyed lookup — and the naming flow should verify the target sessionId before appending ai-title/agent-name entries.
🤖 Generated with Claude Code
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗