[BUG] CCD desktop silently drops sessions on relaunch and has no in-app recovery; CLI --resume produces sessions invisible to the sidebar
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Environment
- CCD desktop, version 2.1.142 (Microsoft Store / MSIX install — package id
Claude_pzs8sxrjxfjjc) - Claude Code CLI, version 2.1.116, at
~/.local/bin/claude - Windows 11
- Repo with 1 main checkout + 5 git worktrees, each running its own session
What happened
Hard power loss during normal use. 6 sessions had been open across the 6 worktrees, including one ~1-week-old session (~148 MB JSONL, ~49,000 turns) that had just opened PR #364 ~2 hours before the outage.
After reboot:
- CCD relaunched and auto-restored only some sessions. Initially 5 of 6 reattached. After a subsequent CCD restart (looking for a recovery UI), only 1 of 6 had a pointer file in
~/.claude/sessions/. The other 5 processes were still running according totasklist, but had no pointer file and no sidebar entry. - The orphaned session's JSONL was fully intact on disk at
~/.claude/projects/<encoded-cwd>/<uuid>.jsonl— last line valid JSON, clean assistant message, timestamps continuous up to the moment of the power cut. - CCD's "Recents" panel never listed it. The project (worktree) is registered in
~/.claude.jsonas a trusted folder, so it's known to CCD; the JSONL is in the right per-project directory; but the desktop sidebar's Recents list (which appears to be a curated index, separate from on-disk JSONL discovery) never had a row for it. - No in-app affordance to recover it. The launcher screen ("What's up next") accepts no
/resumeslash command and exposes no obvious "Open session from file…" or "Attach existing JSONL" control. Filter / sort controls on the Recents header did not surface it either. - CLI-side recovery works but is invisible to CCD. Running
claude --resume <uuid>fromcmdin the worktree directory successfully resumed the session — full history loaded, conversation continued. But the pointer file CLI writes hasentrypoint: "cli", noprocStartfield, and CCD's sidebar filters it out. Result: session is alive, JSONL is being updated, but the desktop app shows nothing.
Confirmed by inspection
Pointer-file comparison for two co-resident processes (both running, both attached to valid sessions):
desktop-spawned session (visible in sidebar):
{"pid":4536,"sessionId":"812bc45d-...","cwd":"...","startedAt":...,
"procStart":"639147170176297300","version":"2.1.142","peerProtocol":1,
"kind":"interactive","entrypoint":"claude-desktop"}
CLI-spawned session (NOT visible in sidebar):
{"pid":8412,"sessionId":"0aafbec7-...","cwd":"...","startedAt":...,
"version":"2.1.116","peerProtocol":1,
"kind":"interactive","entrypoint":"cli"}
Manually editing the CLI pointer to add entrypoint:"claude-desktop" + a synthetic procStart did NOT make CCD surface it, which suggests CCD verifies procStart against the actual Windows process-creation FILETIME via OpenProcess(pid) and rejects mismatches. Good security posture; no user-accessible workaround.
Impact
A user can fully lose access to long-running sessions through CCD UI state alone — even though zero data is lost on disk. For a less technical user there is no way to discover that their session still exists. For me it required filesystem inspection from a shell to find the JSONLs, then a separate cmd window to resume the conversation (without model access, since CLI auth differs from CCD auth).
Suggested fixes (any one would resolve)
- Auto-restore all prior sessions on relaunch, the way browsers offer "restore previous session" after a crash.
- Make "Recents" read on-disk JSONLs in trusted project dirs, not just a curated index. Or expose a "Show all sessions for this project" toggle that does so.
- Add an "Open session from file…" command in the launcher / File menu / Recents header.
- Surface CLI-resumed sessions in the sidebar (treat
entrypoint:"cli"as a legit running session for display purposes, even if the desktop IPC channel is unavailable). At minimum, show them with an indicator so the user knows they exist. - On relaunch, log a banner ("N sessions were not restored — click here to reattach") if any project dirs have JSONLs with recent activity but no live pointer.
Workaround for affected users
From a cmd window in the orphaned session's worktree:
claude --resume <session-uuid>
Session loads in the terminal. Conversation history is intact. Model access depends on CLI auth state. The desktop app will not show this session.
Note
This isn't a one-off — I have at least 5 orphaned sessions on disk after the recent CCD restart cycles. The data is safe, but I cannot access them through the app I normally use. Happy to provide additional diagnostics (full pointer-file contents, version logs, JSONL stat output) if useful.
What Should Happen?
After a relaunch (whether triggered by a crash, power-loss, OS reboot, or normal quit-and-reopen), CCD desktop should make every prior session reachable from the app, without requiring filesystem inspection or terminal commands.
Concretely, any of these would resolve the issue:
- Auto-restore every session that had a JSONL written in the last N days, on every CCD launch.
- Have "Recents" (or a new "All sessions for this project" view) read on-disk JSONLs in trusted project directories, not just CCD's curated session index.
- Add an "Open session from file…" command (launcher, File menu, or Recents header) that lets the user point CCD at an existing JSONL and resume it as a desktop-spawned process.
- Display CLI-resumed sessions (entrypoint: "cli") in the sidebar, with an indicator that distinguishes them, so users at least know the session is alive.
Today none of these exist, and a user whose CCD didn't auto-restore a session has no documented in-app path to get it back.
Error Messages/Logs
Pointer-file comparison between a desktop-visible session and a CLI-resumed session (both processes alive at the same time):
# desktop-spawned (appears in CCD sidebar)
{"pid":4536,"sessionId":"812bc45d-44d5-4e7d-b079-def901482c6a","cwd":"...\\worktrees\\xenodochial-moore-198763","startedAt":1779134618276,"procStart":"639147170176297300","version":"2.1.142","peerProtocol":1,"kind":"interactive","entrypoint":"claude-desktop"}
# CLI-spawned (alive, JSONL updating, but NOT in CCD sidebar)
{"pid":8412,"sessionId":"0aafbec7-acc5-4c4f-a40c-fb06e79650a9","cwd":"...\\worktrees\\xenodochial-albattani-a86d61","startedAt":1779134642509,"version":"2.1.116","peerProtocol":1,"kind":"interactive","entrypoint":"cli"}
Differences: CLI pointer has no `procStart` field and `entrypoint:"cli"` (vs `"claude-desktop"`). Manually patching the CLI pointer to add a synthetic `procStart` + `entrypoint:"claude-desktop"` did NOT cause CCD to show it, which suggests CCD verifies procStart against the real Windows process-creation FILETIME via OpenProcess(pid).
No error messages are surfaced to the user in CCD — that's part of the bug. Sessions disappear silently from the sidebar; no banner, no toast, no warning.
Steps to Reproduce
- Open CCD desktop with several long-running sessions across multiple git worktrees in the same repo.
- Trigger a hard shutdown (power-cut, force-kill, or just
taskkill /F /IM claude.exefor a fast repro). - Relaunch CCD desktop.
- Observe: only a subset of prior sessions reattach (in my case, 1 of 5–6). The Recents panel does not list the dropped sessions.
- Verify the JSONLs are intact on disk at
~/.claude/projects/<encoded-cwd>/<uuid>.jsonl— last line is valid JSON, timestamps continuous up to the moment of shutdown. - Try to find an in-app way to attach the orphaned JSONL: no UI control exists. The launcher input doesn't accept
/resume. No "Open session from file" command. Filter/sort controls on Recents don't surface the JSONL. - Recover via CLI: open cmd in the worktree, run
claude --resume <uuid>. Session loads. JSONL continues updating. CCD desktop sidebar remains empty for that session — because the CLI pointer'sentrypoint:"cli"is filtered out.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.142 (Claude Code desktop); CLI is 2.1.116
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Terminal.app (macOS)
Additional Information
The orphaned session for which I have the most evidence: it created PR #364 in a private repo ~2h before the power-cut, and was last written 2026-05-18 17:33 UTC. JSONL is 148 MB / 49,170 lines, on disk at ~/.claude/projects/C--Users-Gilbert-...-worktrees-xenodochial-albattani-a86d61/0aafbec7-acc5-4c4f-a40c-fb06e79650a9.jsonl. Happy to attach a ~/.claude/sessions/ directory listing or anonymized pointer files if needed.
Showing cached comments. Read the full discussion on GitHub ↗
6 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
🔧 Solution: CCD Session Drop + No Recovery Fix
Root Cause Analysis
Three interconnected failure modes:
~/.claude/sessions/. After hard power loss, pointer files can be corrupted/lost while running processes continue writing JSONL.--resumecreates pointer files withentrypoint: "cli"and noprocStart. CCD filters these out, creating a zombie state — session alive, JSONL updating, but CCD shows nothing.~/.claude/projects/<encoded-cwd>/for orphaned JSONL files.Proposed Fix
Part 1: JSONL-Based Fallback Discovery — Scan all project directories for JSONL files not tracked by pointer files, validate integrity, and surface orphaned sessions.
Part 2: Recovery UI — Add "Session Recovery" dialog on startup when orphaned sessions found, with "Recover All" button.
Part 3: CLI Pointer Visibility — Fix
entrypointand addprocStartfor CLI-resumed sessions so CCD sees them.Part 4: Pointer Backup — Secondary pointer file location as backup for crash recovery.
Implementation Priority
| Priority | Component | Effort | Impact |
|----------|-----------|--------|--------|
| P0 | JSONL fallback discovery | 2-3 days | Prevents silent data loss |
| P0 | Recovery UI | 1-2 days | User-facing recovery path |
| P1 | CLI pointer visibility | 1 day | Cross-tool session sync |
| P1 | Pointer backup | 1 day | Additional resilience |
Files to Modify
Full solution document:
~/.hermes/solutions/claude-code-60341-ccd-session-drop-no-recovery-fix.mdThat is a crazy size for a session!
The large session JSONL being intact is the most important thing here — the conversation history isn't lost, just invisible to the Desktop UI. What's missing is the Desktop's per-session metadata entry: the
local_*.jsonfile in%APPDATA%\Claude\claude-code-sessions\that maps a session list row to its transcript. Power loss can drop those in-flight, leaving the transcript on disk with nothing pointing to it.The confirmation check: look in
%APPDATA%\Claude\claude-code-sessions\<account>\<org>\forlocal_*.jsonfiles. If there are no entries matching your orphaned sessions' UUIDs (the UUIDs come from the.jsonlfilenames in~\.claude\projects\), that confirms the metadata was never flushed.synth_session_metadata.pyfromclaude-code-session-recoveryhandles this — it walks~\.claude\projects\, identifies transcript files with no matching metadata entry, and synthesises thelocal_*.jsonfiles needed to surface them back into the Desktop session list. The ~148 MB session you're worried about should be recovered the same way as the smaller ones.The separate issue of CLI
--resumenot surfacing them in the sidebar is the same root cause from the CLI side — the pointer files in~\.claude\sessions\were likely also lost in the power cut. Synthesising the Desktop metadata entries is the path that gets them back into the UI. Full write-up at #56172.Confirming this on macOS as well, with a deterministic trigger that needs no crash/power-loss — just removing a worktree.
Environment
Deterministic repro
git worktree remove …+ delete theclaude/<name>branch.claude --resumein the terminal still lists every one of them, so the bodies are intact in~/.claude/projects/. The loss is purely in the desktop sidebar.Root cause (what I found digging through the stores)
cwdset to the worktree path, so their bodies are written into a worktree-specific encoded folder:~/.claude/projects/…--claude-worktrees-<name>/.~/Library/Application Support/Claude/claude-code-sessions/<ws>/<proj>/local_*.json), and removing a worktree neither migrates the bodies nor updates that index.git-worktrees.jsonis also left with a dead entry pointing at the deleted path.~/.claude/projects/on startup, so any session "present on disk but absent from the index" stays invisible forever — exactly the "--resumesessions invisible to the sidebar" symptom in the title.Two possible fixes (either solves it)
cwd/gitBranch, recreate thelocal_*.jsoncards, and prunegit-worktrees.json.~/.claude/projects/<cwd>/as the source of truth and auto-create cards for any session missing from the index, so Recents can never lag behind the real session directory.I recovered my sessions by hand-writing the
local_*.jsoncards, but that's filesystem surgery no end user should have to do. Please don't let this go stale — it's silent data-access loss.+1, related but slightly different variant on Windows 11, Claude Desktop v2.1.195.
Multiple long-running Code sessions (one 3000+ messages / 14MB, another 3700+ messages / 30MB) disappeared from the Recents sidebar after a PC freeze/forced restart. Confirmed the .jsonl files are fully intact on disk under ~/.claude/projects/<project>/<id>.jsonl, with continuous timestamps up to the last message.
Important distinction from the entrypoint theory above: I checked the
entrypointfield on every line of both affected session files — both are"entrypoint":"claude-desktop"from the very first message, never touched by the CLI before they vanished. So this isn't (only) about CLI-spawned sessions being filtered out — native desktop-originated sessions can also drop out of the Recents index after a crash, with no entrypoint mismatch to explain it.Tried: in-app search (found nothing), Recents filters (Status/Project/Environment all set to "All" — still no sessions reappeared, list stays capped).
Workaround that worked: installed @anthropic-ai/claude-code via npm, then
claude --resume <id>from the project directory loaded the full history correctly — confirms the data layer is fine, it's purely a sidebar indexing issue. (After this resume, the entrypoint for new turns presumably becomes "cli", which is a separate compounding issue matching what's described above — but the initial disappearance happened before any CLI involvement.)Also submitted via in-app /bug (Feedback ID: 4e33245f-5d42-483e-a008-589353f8d1a2) for reference.
Same underlying defect as this issue (the desktop Recents/sidebar is a curated index separate from on-disk JSONL discovery, so an intact session can be invisible with no in-app recovery), but with a different, fully deterministic trigger worth adding — the original repro (hard power loss) is hard to reproduce.
Trigger: rewind to the first message.
Repro (Windows 11, CCD desktop, claude-code CLI 2.1.207):
Esc-> in the message picker, select the first/earliest message (rewind to the very start).Result:
~/.claude/projects/<encoded-cwd>/<session-id>.jsonlis fully intact on disk (hundreds of user/assistant events).claude --resume <session-id>from the CLI opens the full conversation and continues normally (the JSONL grows correctly with new turns) — but the desktop sidebar still shows the session empty/absent even after another restart.So the rewind-to-first-message path reliably diverges the desktop sidebar index from the on-disk JSONL, and neither an app restart nor a CLI resume+continue re-syncs it. Data is safe (CLI-accessible); the gap is purely the desktop index/UI with no recovery path.
Possibly related: #66423 (rewind "target not on active chain"), #64615 (Esc-Esc rewind destructive), #72047 (data on disk but hidden).