Workflows/agents view hydration relaunch can attach the TUI to a stale session under tmux; agent-name/ai-title stamped onto unrelated sessions

Open 💬 3 comments Opened Jul 5, 2026 by TheMizeGuy

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)

  1. Session A (project X) ran a dynamic-workflow-heavy task inside a tmux pane; it settled: daemon log bg settled 1eb3e5bd (done).
  2. Later, a fresh session B was launched in a different directory (project Y), also in a tmux pane, and the workflow view was opened.
  3. 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"
``

  1. Session A's transcript (1eb3e5bd-….jsonl) received new attachment/system entries minutes after it had settled.
  2. 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 by consumeAgentViewRelaunchMarker() (reads env, deletes it, returns parsed marker), with session start type agents_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

View original on GitHub ↗

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