JSONL cross-session contamination: all event types written to wrong session file when multiple sessions are active

Resolved 💬 5 comments Opened Feb 19, 2026 by MitsunChieh Closed Mar 21, 2026

What's Wrong?

When multiple sessions are active in the same project directory, JSONL entries from one session are written into another session's JSONL file. All event types are affected — not just custom-title, but also assistant, user, system, progress, and queue-operation.

The cross-writes are bidirectional: session A's file contains entries from session B, and session B's file contains entries from session A. Events from different sessions are interleaved at sub-minute (sometimes sub-second) intervals within a single JSONL file.

Quantified impact

Three affected sessions (bfcfcd91, a5d6b936, 9600a743) in the same project:

| File | Entries with sessionId | Cross-session entries | Contamination rate |
|------|----------------------|----------------------|-------------------|
| bfcfcd91 | 61 | 26 | 42.6% |
| a5d6b936 | 1,184 | 276 | 23.3% |
| 9600a743 | 321 | 246 | 76.6% |

Other JSONL files (7) in the same project directory are completely clean.

What Should Happen?

Each session's JSONL file should only contain entries belonging to that session. Entries should never leak into a different session's file.

Steps to Reproduce

Exact reproduction steps are not confirmed. Suspected trigger:

  1. Have multiple Claude Code sessions active simultaneously in the same project directory
  2. Interact with them in overlapping time windows
  3. Inspect the JSONL files — entries from different sessions will be interleaved in each other's files

Note: /resume was not used in the affected sessions (confirmed by scanning all entries for isResume, resumeFrom, source: "resume" — none found). This distinguishes this issue from #26563, which is triggered by /resume.

Evidence

Timeline interleaving in a5d6b936.jsonl

L599:  a5d6b936 ts=16:04:11  (own session)
L605:  9600a743 ts=16:26:37  ← 22min jump, foreign session injected
L617:  a5d6b936 ts=16:33:37  ← back to own session
L627:  bfcfcd91 ts=16:35:15  ← another foreign session
L646:  a5d6b936 ts=16:36:21  ← back to own session
...
L1040: a5d6b936 ts=18:01:33
L1041: bfcfcd91 ts=18:01:36  ← 3 seconds later, different session!
L1043: a5d6b936 ts=18:01:49  ← 13 seconds later, back again

Cross-written event types in a5d6b936.jsonl

141× assistant   (from bfcfcd91)
 98× user        (from bfcfcd91)
 12× system      (from bfcfcd91)
 12× progress    (from bfcfcd91)
  4× user        (from 9600a743)
  3× assistant   (from 9600a743)
  3× custom-title(from bfcfcd91)
  2× system      (from 9600a743)
  1× custom-title(from 9600a743)

Impact

  • Session history is unreliable: JSONL files may contain conversations from other sessions mixed in
  • Session names corrupted: custom-title cross-writes cause wrong names in the resume picker
  • Debugging is extremely difficult: a single JSONL file may contain interleaved entries from 3+ sessions

Claude Code Version

2.1.47 (Claude Code)

Platform

Anthropic API (subscription)

OS

macOS 14.6 (Darwin 23.6.0)

Related Issues

  • #26563 — Hook payload session_id misattributed after /resume (different trigger: /resume vs concurrent sessions; unidirectional vs bidirectional; may share underlying root cause)
  • #26240 — Session names lost after resume
  • #25090 — Auto-titler overwrites manual /rename
  • #24809 — customTitle not restored on resume

View original on GitHub ↗

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