[Bug] Session transcript persistence silently disabled by server-side gate

Open 💬 2 comments Opened Jun 26, 2026 by alexandresee

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 in
claude --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-session
jobs/<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

  1. 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.

  1. Don't gate transcript writes on concurrentSessions pid-file registration

they should be independent.

  1. Fix the register create step (it currently no-ops without logging) and the

resulting updatePidFile ENOENT.

  1. Consider documenting CLAUDE_CODE_FORCE_SESSION_PERSISTENCE and/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

[]

View original on GitHub ↗

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