Bug: a foregrounded background subsession's terminal render is mirrored into an unrelated interactive session's pane (cross-session render leak)

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 1 comment · opened Aug 15, 2026

Summary

With several independent Claude Code sessions running on one machine and one of them running the agent view ("FleetView"), the output of a background subsession appeared, live and byte-identical, in the terminal pane of a different, unrelated interactive session. The two panes are separate processes resuming separate conversations with separate session IDs, yet rendered the same content. On-disk transcripts stayed correct and distinct — only the terminal render was wrong.

Reproducibility (read first)

Not reproduced on demand. It has occurred twice (weeks apart). This report is built from evidence captured after the fact (tmux capture-pane, ps, ListAgents, and the .jsonl transcripts), not from a deterministic recipe. No repro was attempted deliberately, to avoid disrupting live background sessions. Everything under "Measured" is verified; everything under "Hypotheses" is explicitly not.

Impact

  • Session isolation breach: an interactive session in one project displayed another session's live conversation. The operator reasonably believes their work is lost (it is not — the transcript is intact — but the pane shows the wrong session).
  • Possible input misdelivery (unverified): the hijacked pane rendered the other session's pending approval prompt, so keystrokes in it could plausibly land in the wrong session. Not confirmed; noted because it follows from the output misrouting.

Environment

  • macOS. Multiple plain interactive claude --resume <id> sessions in separate tmux panes (distinct project dirs), plus one session running the agent view / FleetView with background, worktree-spawned subsessions.
  • Three Claude Code versions running concurrently and sharing one machine-wide daemon: clients observed at 2.1.220, 2.1.227, 2.1.233; a single daemon at /tmp/cc-daemon-<uid>/<id>/ (one control.sock, a pty/ socket dir, bg-spare/bg-pty-host processes referencing multiple version dirs). This version skew is a likely-relevant condition — see Hypotheses.

Measured (verified facts)

  1. Two panes — Session A (claude --resume <id-A>, project-a) and Session B (claude --resume <id-B>, project-b) — displayed byte-identical live output. Confirmed authoritative via tmux capture-pane -p addressed by unambiguous pane-id, so it is not a terminal-emulator redraw artifact.
  2. The two panes are different processes (verified by ps/pgrep): distinct PIDs, distinct --resume/--session-id arguments, distinct working directories.
  3. The displayed content was in neither pane's own transcript. A's last real message predated the incident; B's was weeks old. (Verified by grepping each ~/.claude/projects/**/<id>.jsonl.)
  4. The content belonged to a third session: a background FleetView subsession (Subsession X) running in a git worktree, which the operator had just foregrounded in the agent view. Session B's pane rendering X is expected; Session A's pane also rendering X is the bug.
  5. ListAgents shows plain interactive sessions auto-enroll as foregroundable peers, e.g. <name> · interactive · tmux <session>:@<win>.%<pane> — with no --bg or agent-view opt-in by the operator.
  6. tmux refresh-client on the affected pane does not clear it (further confirming the corruption is above the terminal layer, in Claude Code).

Minimal inference

The daemon delivered a foregrounded background subsession's PTY output to more than one attached client — including an interactive client that had not selected it. I.e. the foreground/render fan-out is not scoped to the requesting client. This is the smallest claim the measurements support; the specific cause is open (see Hypotheses).

Hypotheses (NOT confirmed)

  • Mixed client versions on one shared daemon (better supported — directly observed): a single daemon serving clients built from three different versions could plausibly misroute a render. This is the condition I'd investigate first.
  • A conversation attached by two clients at once (weakly supported): a second --fork-session --resume fork of one conversation was live during the incident. However, that fork was of a different conversation than the one that actually leaked, so its relevance is uncertain — included only for completeness, not as a proposed cause.

Ruled out (tested)

  • Not a terminal redraw glitch: capture-pane by pane-id shows identical content; refresh-client doesn't clear it.
  • disableAgentView / CLAUDE_CODE_DISABLE_AGENT_VIEW=1 does NOT prevent enrollment. After relaunching an affected pane with the env var set, the session re-registered as an interactive peer within ~23s (verified via ListAgents). It disables the agent-view UI and the on-demand daemon spawn, but a session still joins an already-running daemon, so there is no working per-session isolation opt-out while FleetView keeps a daemon alive.

Workaround (operator-side, not a fix)

Kill the affected pane's client process and relaunch its --resume; a clean single attach re-binds correctly. The transcript is durable, so no data is lost.

Suggested fix direction

  • Scope a foregrounded subsession's render strictly to the client that requested it; never fan a PTY out to a client that did not select it.
  • Provide a real per-session isolation opt-out that holds even when a daemon is already running (disableAgentView currently does not achieve this).
  • If mixed-version clients on one daemon are unsupported, detect and refuse the mismatch rather than misrouting silently.

Related

  • #51887 (closed) — "Session recap contains content from a different, unrelated conversation": same family (cross-session content leak), different surface (recap generation, not PTY render).
  • #82491 (closed) — "cross-session output bleed" — was a false alarm (reporter's own wc shell function shadowing the binary). This report is not a duplicate of it: here the sessions are genuinely distinct processes and the leak is verified from both sides' transcripts.
  • #86775 (open) — background sessions never receive SIGWINCH; likely the cause of a separate cosmetic resize/redraw glitch seen alongside this, not this leak.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗