[BUG] Programmatically-spawned sessions intermittently write a stub transcript (ai-title only) + no sessions/<PID>.json -> not resumable (2.1.173, Windows)
Summary
On Windows, sessions started programmatically (a launcher process opens a new
terminal tab and runs claude with a positional first-message prompt) intermittently
persist their transcript as a stub: the <project>/<sessionId>.jsonl file contains
only a single {"type":"ai-title",...} line (~110–120 bytes) and no~/.claude/sessions/<PID>.json is ever created — even though the session runs for
minutes, executes many tool calls, fires hooks, and writes files to disk.
Because the transcript was never written, claude --resume has nothing to restore and
silently starts a new session. The conversation context is permanently lost. The
work the session produced (files on disk) survives; only the resumable transcript is gone.
Interactive sessions started by hand, and claude --resume sessions, are healthy 100%
of the time on the same version. Only programmatically-spawned sessions are affected,
and only intermittently.
(Possibly related but distinct: #57203 is macOS and the transcript exists yet is missing
from the resume list; here the transcript is never written and the PID file is absent.)
Environment
- Claude Code: 2.1.173 (npm global install)
- OS: Windows 11 (10.0.26200)
- Shell/terminal: Windows Terminal tab running PowerShell;
claude.exe(node) - How spawned: a launcher script generates a tab that runs roughly
claude --append-system-prompt "<system prompt>" "read todo and start working"
(positional first message → interactive mode with an initial prompt, not piped stdin).
Symptom
For an affected (stub) session:
~/.claude/projects/<encoded-cwd>/<sessionId>.jsonlis ~110–120 bytes, containing
only one line: {"type":"ai-title", ...}. No user/assistant/tool messages are ever
appended, despite the session actively working.
~/.claude/sessions/<PID>.jsonis never created for that PID.- The session otherwise behaves normally: PreToolUse/PostToolUse hooks run, tool calls
execute, files are written, the model produces a long multi-turn agentic loop.
- Later,
claude --resumedoes not list / cannot restore the session → a fresh session
is created and the prior context is unrecoverable.
Reliable discriminator (healthy vs stub) — 100% consistent in our data
| | Healthy session | Stub session |
|---|---|---|
| ~/.claude/sessions/<PID>.json | exists | missing |
| <project>/<sessionId>.jsonl | grows (KB–MB) | frozen at ~110 B (ai-title only) |
| claude --resume | restores | starts new session |
The missing sessions/<PID>.json is the cleanest live tell that a session will end up a stub.
Regression window
- Programmatically-spawned workers were healthy on an earlier version (mid-May 2026,
~2.1.168 era — full multi-MB transcripts).
- After updating to 2.1.173 (2026-06-11), spawned workers became predominantly stubs.
- Manual interactive sessions and
--resumesessions remained healthy on 2.1.173.
This points to a regression between the mid-May build and 2.1.173, in the
transcript/PID-file initialization path, that manifests for programmatic spawns.
What we ruled out (so you don't have to)
We spent a day bisecting hypotheses on our side; all of the following were disproven:
- Concurrency / racing parallel starts. A single solo spawn in an idle window
(CPU ~6%, no other claude starting) still produced a stub. Serializing starts did not help.
- Foreground vs background / window focus. Both a focused new window and a background
tab produced stubs.
- The launcher invocation pattern itself. One clean-spawn worker with the exact same
launcher/auto-prompt pattern came out healthy (multi-hundred-KB transcript) — so the
pattern can work; it just usually doesn't.
- Version alone. Manual + resume sessions are healthy on 2.1.173.
Strongest remaining (unconfirmed) correlation: healthy = manual / resume / one early
spawn; stub = later programmatic spawns. Candidate explanations we could not confirm:
(a) a 2.1.173 regression specific to programmatically-spawned sessions, or
(b) host resource state changing over time.
Minimal repro (intermittent — may need several attempts)
- From a parent process, open a new terminal and run
claudewith a positional
first-message prompt that triggers a long, multi-step agentic loop (so the session
stays alive ~60s+, like a real task — a trivial one-shot prompt that exits immediately
is NOT representative and only ever yields the ai-title line):
````
claude --append-system-prompt "<any system prompt>" "do a multi-step task: read some files, edit one, run a command, then stop"
- While it runs, check whether
~/.claude/sessions/<PID>.jsonappears for the new
claude PID.
- After it finishes, inspect
~/.claude/projects/<encoded-cwd>/<sessionId>.jsonl.
Expected: transcript grows; sessions/<PID>.json exists; session is resumable.
Actual (intermittent on 2.1.173): transcript stuck at the single ai-title line; nosessions/<PID>.json; not resumable.
Impact
Any automated/orchestrated spawning of Claude Code sessions on Windows can silently lose
the full conversation transcript while appearing to work. The loss is invisible until you
try --resume and get a new empty session.
Questions / asks
- Is there a known race/regression in the transcript +
sessions/<PID>.json
initialization for non-interactively-spawned sessions on Windows in 2.1.173?
- Is the
ai-title-only stub a recognized failure mode? - Any guidance on a startup signal we can poll to know a session has fully initialized its
persistence (so a launcher can detect/retry stubs)?
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗