~/.claude/sessions/<pid>.json's sessionId not updated on /clear (inconsistent with #88845)

Status Open
Maintainer reply None cached
Activity 0 comments · opened Sep 18, 2026

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>/*.jsonl for new sibling files with type: "file-history-snapshot" on line 0 as the /clear marker
  • 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 sessionId IS updated in the /rename + /clear + return path. The inconsistency (updated in some paths, not in /clear) suggests the write mechanism exists; extending it to fire on /clear should be small.
  • #44607 — "No way to access session ID from within a running session." External consumers rely on sessions/<pid>.json as the workaround; that workaround is broken by this bug.
  • #95029, #71437, #37451, #27329, #36113 — assorted /clear semantics 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).

View original on GitHub ↗