JSONL cross-session contamination: all event types written to wrong session file when multiple sessions are active
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:
- Have multiple Claude Code sessions active simultaneously in the same project directory
- Interact with them in overlapping time windows
- 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-titlecross-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:/resumevs 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
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗