~/.claude/sessions/<pid>.json's sessionId not updated on /clear (inconsistent with #88845)
Summary
~/.claude/sessions/<pid>.json's sessionId field is not updated when the user runs /clear, even though /clear internally generates a new session UUID and starts a new JSONL file. External consumers that reverse-map "sessionId → pid" via the runtime registry route to the pre-/clear (now-frozen) transcript instead of the current live one.
Related to #88845 (which acknowledges the sessionId field IS updated on some paths — specifically after /rename + /clear + return-to-original) — showing the behavior is inconsistent, not universally absent.
Reproduction
Run on macOS/Linux with any recent Claude Code (verified across v2.1.117, v2.1.123, v2.1.204):
# 1. Start Claude Code
claude
In another terminal:
# 2. Observe the pid and current sessionId
CLAUDE_PID=$(pgrep -n claude)
cat ~/.claude/sessions/${CLAUDE_PID}.json | jq -r .sessionId
# → prints, e.g., "aaaaaaaa-1111-1111-1111-111111111111"
# 3. Observe the current active JSONL
ls -t ~/.claude/projects/*/*.jsonl | head -1
# → e.g., .../aaaaaaaa-1111-1111-1111-111111111111.jsonl
Back in Claude Code:
you> (type anything, e.g. "hello")
you> /clear
you> (type anything, e.g. "hello again")
Back in the other terminal:
# 4. Same pid, but the ACTIVE JSONL is now a different sid
ls -t ~/.claude/projects/*/*.jsonl | head -1
# → .../bbbbbbbb-2222-2222-2222-222222222222.jsonl (NEW sid)
# 5. But the runtime registry still says the OLD sid
cat ~/.claude/sessions/${CLAUDE_PID}.json | jq -r .sessionId
# → "aaaaaaaa-1111-1111-1111-111111111111" ← STALE
The updatedAt field of the registry file bumps, but sessionId does not.
Expected
After /clear, ~/.claude/sessions/<pid>.json's sessionId field should equal the UUID of the JSONL Claude is currently writing to.
Actual
sessionId is frozen at the value present when the process started (or was last set by a path like /rename + return-to-pre-clear per #88845). It does not track the current active JSONL when /clear creates a new session UUID.
Impact
Any external tool that reverse-maps sessionId → pid via this registry routes to a stale, no-longer-being-written JSONL. This affects session viewers, automation hooks, and terminal integrations that need to correlate current sid with a pid.
Multiple third-party Claude Code clients have independently built workarounds because ~/.claude/sessions/<pid>.json cannot be trusted for "current sid" — e.g. mnemo-desktop #73 chose to reverse-map pid → sid via claude agents --json --all rather than the runtime file, and mnemo #288 introduced a daemon-side roster.json for the same purpose. That different consumers converge on rolling their own mapping infrastructure suggests the runtime file's sessionId semantics are widely regarded as unreliable.
Workarounds specifically for the /clear staleness require:
- Scanning
~/.claude/projects/<encoded-cwd>/*.jsonlfor new sibling files withtype: "file-history-snapshot"on line 0 as the/clearmarker - Cross-checking that the pid's cwd matches and that only one claude is in the cwd
None of this should be necessary if the registry file were kept authoritative.
Related issues
- #88845 — describes that
sessionIdIS updated in the/rename + /clear + returnpath. The inconsistency (updated in some paths, not in/clear) suggests the write mechanism exists; extending it to fire on/clearshould be small. - #44607 — "No way to access session ID from within a running session." External consumers rely on
sessions/<pid>.jsonas the workaround; that workaround is broken by this bug. - #95029, #71437, #37451, #27329, #36113 — assorted
/clearsemantics complaints (session name reset / new-session-created), some of which may share the same underlying "which state should follow the new sid" ambiguity.
Suggested fix
At the point where /clear calls setConversationId(randomUUID()) (or equivalent), also rewrite ~/.claude/sessions/<pid>.json's sessionId field. Atomically, matching whatever path already handles the update in #88845's scenario.
If there's a reason not to (e.g., sessions/<pid>.json is intended to reflect the process's original session and not the current one), please document it — currently the field's meaning is ambiguous, and third-party consumers reasonably assume "current."
Version
Reproduced on Claude Code v2.1.117, v2.1.123, v2.1.204 (macOS 14.5).