[Bug] Session transcript persistence silently disabled by server-side gate
Bug Description
Bug report — silent transcript loss (session-persistence disabled)
Title: Conversation transcripts silently stop persisting — no .jsonl written,
sessions vanish from --resume; CLAUDE_CODE_FORCE_SESSION_PERSISTENCE=1 restores it
Impact
For ~5 days (onset ~June 20), interactive sessions wrote no transcript —~/.claude/projects/<cwd>/<id>.jsonl is never created. Sessions don't appear inclaude --resume, and a clean exit flushes nothing (the conversation is
unrecoverable once the process ends). It is silent — no warning to the user.
Multi-repo, every new session affected. file-history/ still works, so file edits
survived, but days of conversation history across many projects were lost. The only
recovery was /export on still-running sessions (and gcore memory dumps).
Environment
- Linux, native install (
~/.local/bin/claude→~/.local/share/claude/versions/<v>) - Reproduced identically on 2.1.177 through 2.1.193 (current 2.1.193; exe-confirmed on 2.1.183, build
9d251abd, 2026-06-18) - Many concurrent sessions (~16),
cleanupPeriodDays: 99999
Symptom / debug evidence
With --debug --debug-to-stderr at CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose, every
session logs, repeating every few seconds:
[concurrentSessions] updatePidFile failed: ENOENT: no such file or directory,
open '~/.claude/sessions/<pid>.json'
while ~/.claude/sessions/ exists and is writable. Notably,[concurrentSessions] register failed: is never logged — so the initial
pid-file create step silently no-ops, and the heartbeat update then ENOENTs
forever. sessions/ stays empty (0 pid files for N live sessions); the per-sessionjobs/<id> watch also ENOENTs. No statsig/checkGate decision is logged even at
verbose. Transcript persistence appears gated behind this registration.
Smoking gun: the fix confirms a silently-disabled persistence gate
Launching with CLAUDE_CODE_FORCE_SESSION_PERSISTENCE=1 restores both the
pid-file registration (sessions/<pid>.json is written, with full metadata) and
the .jsonl transcript (verified: a complete 80 KB / 51-line transcript for a
2-turn session, vs. zero bytes without the flag, across multiple A/B sessions).
This strongly indicates session persistence was silently defaulted OFF — most
likely a server-side gate/config that rolled out ~June 20 (matches the onset and
explains why the same 2.1.183 binary persisted transcripts on June 19 and fails
now). The force flag overrides the default.
Ruled out (so this isn't user error or a single-version regression)
- Version: identical on 2.1.177–2.1.193; downgrading does not help (same binary
behaved differently before/after June 20 → external trigger, not the binary).
- Concurrency: persists at 1–2 concurrent sessions, not just under load.
- Local state: persists after deleting + recreating
~/.claude/{sessions,jobs}
fresh and writable.
- Disk / permissions: ample free space; dirs owner-writable (manual writes succeed).
Requests
- Never silently disable transcript persistence. If a gate/default turns it
off, surface it loudly (a startup warning, not a silent skip) — this caused days
of unnoticed data loss.
- Don't gate transcript writes on
concurrentSessionspid-file registration —
they should be independent.
- Fix the
registercreate step (it currently no-ops without logging) and the
resulting updatePidFile ENOENT.
- Consider documenting
CLAUDE_CODE_FORCE_SESSION_PERSISTENCEand/or making
persistence the default for interactive sessions regardless of the gate.
Environment Info
- Platform: linux
- Terminal: gnome-terminal
- Version: 2.1.191
- Feedback ID: 7f85ce8d-8b72-4808-aaac-a501ca0b15b5
Errors
[]This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗