anthropics / anthropics/claude-code
~/.claude/sessions/<pid>.json's sessionId not updated on /clear (inconsistent with #88845)
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
## Summary
`~/.claude/sessions/.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):
```bash
# 1. Start Claude Code
claude
```
In another terminal:
```bash
# 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:
```bash
# 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/.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/.json` cannot be trusted for "current sid" — e.g. [mnemo-desktop #73](https://github.com/xyrlan/mnemo-desktop/issues/73) chose to reverse-map pid → sid via `claude agents --json --all` rather than the runtime file, and [mnemo #288](https://github.com/xyrlan/mnemo/issues/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//*.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/.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/.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/.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).
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the stale sessionId after /clear using the ~/.claude/sessions/.json and JSONL paths shown in the issue. Find the /clear handler where setConversationId(randomUUID()) is called, then compare its registry update behavior with the path discussed in #88845. Done means the registry sessionId matches the currently written JSONL after /clear, with the existing update behavior preserved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100