[BUG] CCD desktop silently drops sessions on relaunch and has no in-app recovery; CLI --resume produces sessions invisible to the sidebar

Status Open
Reported on v2.1.142
Maintainer reply None cached
Activity 8 comments · opened May 18, 2026

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:

  1. 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 to tasklist, but had no pointer file and no sidebar entry.
  2. 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.
  3. CCD's "Recents" panel never listed it. The project (worktree) is registered in ~/.claude.json as 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.
  4. No in-app affordance to recover it. The launcher screen ("What's up next") accepts no /resume slash 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.
  5. CLI-side recovery works but is invisible to CCD. Running claude --resume <uuid> from cmd in the worktree directory successfully resumed the session — full history loaded, conversation continued. But the pointer file CLI writes has entrypoint: "cli", no procStart field, 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)

  1. Auto-restore all prior sessions on relaunch, the way browsers offer "restore previous session" after a crash.
  2. 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.
  3. Add an "Open session from file…" command in the launcher / File menu / Recents header.
  4. 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.
  5. 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:

  1. Auto-restore every session that had a JSONL written in the last N days, on every CCD launch.
  2. 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.
  3. 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.
  4. 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

  1. Open CCD desktop with several long-running sessions across multiple git worktrees in the same repo.
  2. Trigger a hard shutdown (power-cut, force-kill, or just taskkill /F /IM claude.exe for a fast repro).
  3. Relaunch CCD desktop.
  4. Observe: only a subset of prior sessions reattach (in my case, 1 of 5–6). The Recents panel does not list the dropped sessions.
  5. 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.
  6. 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.
  7. 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's entrypoint:"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.

View original on GitHub ↗

6 Comments

github-actions[bot] · 3 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/59736
  2. https://github.com/anthropics/claude-code/issues/38691
  3. https://github.com/anthropics/claude-code/issues/58670

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

jshaofa-ui · 3 months ago

🔧 Solution: CCD Session Drop + No Recovery Fix

Root Cause Analysis

Three interconnected failure modes:

  1. Pointer File Dependency (Primary): CCD relies entirely on pointer files in ~/.claude/sessions/. After hard power loss, pointer files can be corrupted/lost while running processes continue writing JSONL.
  1. Entrypoint Filtering (Secondary): CLI --resume creates pointer files with entrypoint: "cli" and no procStart. CCD filters these out, creating a zombie state — session alive, JSONL updating, but CCD shows nothing.
  1. No JSONL Discovery (Missing): No mechanism to scan ~/.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 entrypoint and add procStart for 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

apps/desktop/src/session-recovery.ts       [NEW]
apps/desktop/src/components/SessionRecoveryDialog.tsx [NEW]
apps/desktop/src/session/pointer-backup.ts [NEW]
cli/src/session/pointer.ts                 [MODIFY]
apps/desktop/src/main.ts                   [MODIFY]

Full solution document: ~/.hermes/solutions/claude-code-60341-ccd-session-drop-no-recovery-fix.md

BasedGPT · 3 months ago

That 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_*.json file 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>\ for local_*.json files. If there are no entries matching your orphaned sessions' UUIDs (the UUIDs come from the .jsonl filenames in ~\.claude\projects\), that confirms the metadata was never flushed.

synth_session_metadata.py from claude-code-session-recovery handles this — it walks ~\.claude\projects\, identifies transcript files with no matching metadata entry, and synthesises the local_*.json files 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 --resume not 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.

yuantee · 2 months ago

Confirming this on macOS as well, with a deterministic trigger that needs no crash/power-loss — just removing a worktree.

Environment

  • Claude desktop app, Code tab — macOS (Darwin 25.5)
  • Sessions had been created via the app's built-in "worktree" feature

Deterministic repro

  1. In the app, start a session for a project with "worktree" enabled; have a few turns.
  2. Remove the worktree normally: git worktree remove … + delete the claude/<name> branch.
  3. Restart the app → those sessions are gone from Recents.

claude --resume in 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)

  • Worktree sessions get their cwd set to the worktree path, so their bodies are written into a worktree-specific encoded folder: ~/.claude/projects/…--claude-worktrees-<name>/.
  • The Code sidebar reads only its private index (~/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.json is also left with a dead entry pointing at the deleted path.
  • The app never reconciles its index against ~/.claude/projects/ on startup, so any session "present on disk but absent from the index" stays invisible forever — exactly the "--resume sessions invisible to the sidebar" symptom in the title.

Two possible fixes (either solves it)

  • A. Migrate on worktree removal — move the bodies back into the base-repo encoded folder, rewrite their cwd/gitBranch, recreate the local_*.json cards, and prune git-worktrees.json.
  • B. Reconcile on startup — treat ~/.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_*.json cards, 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.

Mede425 · 2 months ago

+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 entrypoint field 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.

15230745073 · 1 month ago

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):

  1. Open a project session in the desktop app with a long history (hundreds of exchanges).
  2. Double-tap Esc -> in the message picker, select the first/earliest message (rewind to the very start).
  3. The view collapses to the start and that first prompt is loaded into the input box.
  4. Restart the desktop app.

Result:

  • The session now shows in the project sidebar as an empty "General coding session" (default title); content not displayed.
  • Restarting CCD does not restore it.
  • The transcript ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl is 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.
  • No in-app affordance to recover or re-index it (matches this issue).

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).

Showing cached comments. Read the full discussion on GitHub ↗