/clear doesn't update PID session file, causing stale sessionId in ~/.claude/sessions/<pid>.json

Resolved 💬 4 comments Opened May 6, 2026 by gabemahoney Closed May 6, 2026

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 ps shows 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 --resume the correct session after a process restart) will resume the wrong conversation — the pre-/clear session instead of the post-/clear one

Reproduction

  1. Start a Claude Code session — note the session ID in ~/.claude/sessions/<pid>.json
  2. Run /clear
  3. Check ~/.claude/sessions/<pid>.json — the sessionId field still shows the old value
  4. 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.tsregenerateSessionId() (line ~435), switchSession() (line ~468)
  • src/utils/concurrentSessions.tsregisterSession() / onSessionSwitch callback (line ~98)
  • src/commands/clear/conversation.ts/clear calling regenerateSessionId() (line ~203)

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗