/clear doesn't update PID session file, causing stale sessionId in ~/.claude/sessions/<pid>.json
Bug
/clear regenerates the session ID but does not update ~/.claude/sessions/<pid>.json, causing the PID file's sessionId to go stale. Any external tooling that reads the PID file to discover the active session ID gets the pre-/clear value.
Root cause
Two code paths mutate STATE.sessionId:
| Path | Function | Emits sessionSwitched? |
|------|----------|------------------------|
| --resume / /resume | switchSession() | Yes ✅ |
| /clear | regenerateSessionId() | No ❌ |
The PID file update is hooked to sessionSwitched in concurrentSessions.ts:98-103:
// --resume / /resume mutates getSessionId() via switchSession. Without
// this, the PID file's sessionId goes stale and `claude ps` sparkline
// reads the wrong transcript.
onSessionSwitch(id => {
void updatePidFile({ sessionId: id })
})
But regenerateSessionId() in state.ts:435-449 sets the new ID without emitting:
export function regenerateSessionId(options = {}): SessionId {
if (options.setCurrentAsParent) {
STATE.parentSessionId = STATE.sessionId
}
STATE.planSlugCache.delete(STATE.sessionId)
STATE.sessionId = randomUUID() as SessionId
STATE.sessionProjectDir = null
return STATE.sessionId
// ← missing: sessionSwitched.emit(STATE.sessionId)
}
Impact
claude psshows the wrong sparkline/transcript after/clear(as noted in the existing comment)- External tooling using PID files for session discovery (e.g., managed Claude Code sessions that need to
--resumethe correct session after a process restart) will resume the wrong conversation — the pre-/clearsession instead of the post-/clearone
Reproduction
- Start a Claude Code session — note the session ID in
~/.claude/sessions/<pid>.json - Run
/clear - Check
~/.claude/sessions/<pid>.json— thesessionIdfield still shows the old value - The exit message says "Resume this session with: claude --resume <new-id>" but the PID file has the old ID
Suggested fix
Add sessionSwitched.emit(STATE.sessionId) at the end of regenerateSessionId():
export function regenerateSessionId(options = {}): SessionId {
if (options.setCurrentAsParent) {
STATE.parentSessionId = STATE.sessionId
}
STATE.planSlugCache.delete(STATE.sessionId)
STATE.sessionId = randomUUID() as SessionId
STATE.sessionProjectDir = null
sessionSwitched.emit(STATE.sessionId) // ← fix
return STATE.sessionId
}
The only current subscriber is the PID file updater, so the blast radius is zero beyond the intended fix.
Environment
- Claude Code 2.1.101
- Linux (Ubuntu)
Source references
src/bootstrap/state.ts—regenerateSessionId()(line ~435),switchSession()(line ~468)src/utils/concurrentSessions.ts—registerSession()/onSessionSwitchcallback (line ~98)src/commands/clear/conversation.ts—/clearcallingregenerateSessionId()(line ~203)
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗