Desktop app update deletes session history (sessions-index.json + .jsonl files)
Bug description
After updating the Claude Code desktop app (from versions 2.1.34/2.1.63/2.1.92 → 2.1.101), session history was partially or fully deleted across multiple projects.
What was lost
| Project | sessions-index.json | .jsonl session files | Status |
|---------|-------------------|---------------------|--------|
| Project A (150+ hours of work) | Deleted | All deleted | Complete data loss |
| Project B | Deleted | All deleted | Complete data loss |
| Project C | Deleted | 10 files survived | Index lost, data intact |
| Project D | Deleted | 3 files survived | Index lost, data intact |
| Project E | Survived (old entry points to deleted .jsonl) | 1 old session deleted, current survived | Partial loss |
Impact
- Two projects lost all session history permanently — no .jsonl files remain, no sessions-index.json
- Two projects lost their sessions-index.json but the .jsonl data files survived — sessions disappeared from the sidebar but could be reconstructed by rebuilding the index
- One project had an old session .jsonl deleted but the index file survived (with a stale reference)
The inconsistency (some projects lost only the index, others lost everything) suggests the cleanup/migration logic during the update is not working correctly.
Steps to reproduce
- Have multiple projects with session history across different directories
- Update the Claude Code desktop app to 2.1.101
- Open the app — session history is gone from the sidebar
- Check
~/.claude/projects/— sessions-index.json files are missing, and for some projects the .jsonl files are also deleted
Expected behavior
App updates should preserve all session history. If a migration is needed, it should be non-destructive.
Environment
- macOS 26.5
- Claude Code desktop app, updated to 2.1.101
- Previous versions: 2.1.34, 2.1.63, 2.1.92
Additional context
- No git repo tracked the
~/.claude/directory, so there is no backup of session files - No Time Machine backups were available
- The
.claude/directory is in.gitignorefor all projects, so session data was never committed - Session data is stored locally only and does not sync to claude.ai, making this data loss permanent
- The sessions-index.json files could be reconstructed from surviving .jsonl files (by parsing sessionId, timestamps, and first prompt from the JSONL entries), but for projects where .jsonl files were also deleted, recovery is impossible
16 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
Same issue happened to me yesterday, sessions are completely gone, even on the browser version.
Confirming this on 2.1.126 (Windows 11) with two additional findings I haven't seen reported yet:
1. Manual restoration is not durable — the cleanup is recurring, not one-shot
When I copied a deleted
.jsonlback into~/.claude/projects/<encoded-path>/from a backup, restarted the desktop app, and waited, the cleanup re-deleted the restored file on the next sync cycle. I reproduced this for 7 different sessions across 5 project folders. Plain file restoration on its own does not survive.2. CLI re-registration appears to make a restored file persist (hypothesis, limited evidence)
Restoring the file and then running:
…from the original cwd seems to register the session with the cloud-side registry, after which the local
.jsonlhas not been re-pruned in my testing. I scripted this for 7 deleted sessions and all 7 are still present immediately after the operation. Caveat: small sample, limited verification window — I haven't yet confirmed durability across multiple cleanup cycles or app restarts. The strongest data point I have is one earlier session (f8780829) that was CLI-resumed several days ago and is still on disk now.This is consistent with — but does not prove — a hypothesis that the cleanup uses cloud-registry membership as the retain/delete signal for local files, rather than just file presence on disk. Maintainer confirmation would be helpful here.
Forensic evidence consistent with the cloud-registry-mismatch hypothesis
$Recycle.Binfor both.jsonlfiles and items originating from.claude\projects— zero hits in either case. So the deletion isDeleteFile()(Win32), not shell delete. Recovery via Recycle Bin is impossible.%APPDATA%\Claude\IndexedDB\https_claude.ai_0.indexeddb.leveldb\and%APPDATA%\Claude\Local Storage\leveldb\for the deleted UUIDs — zero hits. Conversely, sessions that survived have entries in both.git-worktrees.jsonis empty ({"worktrees": {}}). This is not a Cowork-worktree GC. Project files (the actual work output Claude wrote) are intact — only the conversation transcripts are deleted..jsonlwith a fresh UUID, which is not linked to the deleted one. So the cloud-side label survives but the back-pointer to local content is broken.Suggestion
A pragmatic interim fix that wouldn't require redesigning the cleanup: on app launch, scan
~/.claude/projects/and import any local.jsonlUUIDs that are not yet in the cloud registry. That would self-heal the orphan state instead of treating registry-absence as a deletion authority.If retention pruning is intentional (per #46621), please at minimum:
"sessionRetention": "indefinite" | "30d" | …) insettings.json.(uuid, original_path, timestamp, reason)so users can audit data loss.Hit this bug on macOS (MacBook Pro M3). Lost all session history across multiple projects after a Claude Desktop app update.
What I found after investigating:
~/.claude/projects/had only 1 project folder remaining (out of several I had worked in)~/Library/Application Support/Claude/claude-code-sessions/had only small metadata JSON files — no conversation content~/Library/Application Support/Claude/local-agent-mode-sessions/had no session files at all~/.claude/backups/was emptyThe actual .jsonl conversation files were deleted by the update, not just the index. There is no recovery path.
The UI symptom was mixed — some sessions showed "No messages yet", others were missing from the sidebar entirely, and one session (the most recent one) was intact. This patchy pattern is what led me to investigate the filesystem directly.
This is a significant data loss issue. Weeks of conversation history and context are gone with no warning, no export option, and no way to restore. Please prioritize a fix — at minimum, the update process should never delete .jsonl files, and ideally, a backup should be made before any migration runs.
Hey ShreeshaJay,
The re-deletion on the next sync cycle is a key finding — it narrows the problem significantly. The Desktop's cleanup pass appears to be treating restored
.jsonlfiles as orphans and removing them, which points to why your restoration didn't hold: without a correspondinglocal_*.jsonmetadata entry in%APPDATA%\Claude\claude-code-sessions\, the Desktop has no record that the restored transcript belongs to any session. The cleanup pass sees an unregistered file and removes it.Your CLI re-registration hypothesis is probably right — registering through the CLI likely creates enough of an entry for the cleanup pass to treat the file as legitimate. The more durable fix is synthesising the full metadata entry: a
local_*.jsonfile with the session title, timestamp, andcliSessionIdwired to the restored transcript UUID. That's whatsynth_session_metadata.pyinclaude-code-session-recoverydoes — it creates metadata entries from transcript files, which should make the Desktop treat those files as owned sessions rather than orphans.Worth trying on one session before applying it to all of them, since your finding that plain restoration doesn't survive a sync cycle is something I haven't seen documented elsewhere. Full write-up at #56172.
That massively sucks and I hope that I can help you recover it. Here's what I think might be going on:
From what you've described, it looks like the situation differs across your projects — so it might be worth treating them separately.
For Projects C and D — the
.jsonltranscript files survived but thesessions-index.jsonwas deleted. That's actually the more recoverable case: the conversation history is on disk, it's just that Desktop has nothing to render in the session list. On macOS the equivalent of the Windows metadata layer lives at~/Library/Application Support/Claude/claude-code-sessions/— if you check that directory and find it empty (or missing entries for the affected projects), that confirms the index was the only casualty. I built a tool for exactly this —synth_session_metadata.pyfromclaude-code-session-recovery. It walks~/.claude/projects/, finds transcript files with no valid metadata pointer, and synthesises the entries needed to surface them back in the session list. The toolkit is Windows-tested but the file formats are identical on macOS — the scripts need path adjustments for the macOS metadata location, but the logic transfers directly.For Projects A and B — the
.jsonlfiles were also deleted. Before concluding those are gone, check Time Machine (if enabled) and any cloud sync covering your home directory;~/.claude/projects/often falls outside typical backup scope, but it's worth checking. If a snapshot covers the period before the update, the transcripts would be there.Full write-up at #56172.
Following up on my earlier comment. I ran the recovery toolkit today on macOS (MacBook Pro M3) and wanted to document the full findings for anyone else hitting this on Mac.
Environment
Running the toolkit on macOS
The toolkit is Windows-native so the path detection doesn't work directly on Mac. The fix is to create a fixture directory with symlinks pointing at the macOS equivalents, then pass
--state:The
--stateflag is also required for the repair script andfind_missing_jsonls_in_backup.py, otherwise they either error with "state schema not recognised" or compute a different diagnosis ID (token mismatch). Passing--stateto both resolved this.What diagnose.py found
Dry-run output from repair_session_metadata.py
All 6 sessions missing
cliSessionIdcame back asORPHAN — no JSONL match in window. The sessions lost were:Repaired: 0 / Refused: 0 / Orphan: 6— nothing to repair because the.jsonlfiles themselves were deleted by the app update, not just unlinked from metadata.find_missing_jsonls_in_backup.py output
Conclusion
The toolkit worked correctly and the macOS path workaround is straightforward. The data loss in my case is confirmed unrecoverable — the
.jsonlfiles were deleted outright by the app update, not just orphaned from their metadata. The toolkit correctly diagnosed this and didn't attempt a false repair.For anyone else on macOS hitting the token mismatch error: add
--state <your-fixture-path>to the repair script invocation, same as diagnose. That resolves it.Update: while testing I also noticed that
find_missing_jsonls_in_backup.pywas the only script that didn't receive the native macOS/Linux path detection from commit0609930—diagnose.pyandrepair_session_metadata.pywere both updated but this one was missed. I've submitted a fix upstream: https://github.com/BasedGPT/claude-code-session-recovery/pull/6Hope this macOS walkthrough helps others. Thanks to the maintainer for building this — even a confirmed-unrecoverable diagnosis is genuinely useful closure.
Also affected — Windows 11, v2.1.149
Confirming this with additional technical detail in case it helps diagnosis.
Inspecting the session metadata files at:
%APPDATA%\Roaming\Claude\claude-code-sessions\{workspace-uuid}\{store-uuid}\local_{session-uuid}.jsonAll affected sessions have
"transcriptUnavailable": truewith nocliSessionIdfield.Post-redesign sessions that work correctly have a
cliSessionIdpointing to a.jsonlfile under
~\.claude\projects\{project}\. No such file exists for any pre-redesign session.Scale: 25 of 27 sessions affected, oldest dating to 2026-02-01.
The session metadata (title, cwd,
completedTurns, timestamps) survives intact — onlythe transcript content is gone. This points to a storage format migration that was never
performed, rather than accidental file deletion.
Workaround for future sessions: back up these two locations incrementally:
~\.claude\projects\(transcript JSONL files)%APPDATA%\Claude\claude-code-sessions\(session metadata index)Thanks for documenting this, legend — it's the first confirmed macOS run of the toolkit and it's genuinely useful to have the
--statefixture approach written up in a public thread.The key result: the toolkit correctly identified both failure modes present in your setup — six sessions with missing
cliSessionId, two with acliSessionIdpointing at transcript files that don't exist on disk — and returnedRepaired: 0 / Orphan: 6without attempting a false repair. That's the right outcome. No JSONL to link to, so no link gets synthesised.The
--statefixture approach (symlinks to the macOS equivalents, then passing--stateto each script) confirms the core logic transfers without modification. Path detection is the only platform-specific part. I'll add native macOS path detection so the workaround isn't needed in a future release, and I'll document your steps in the meantime.Full write-up at #56172.
Hey jmichelmore,
The
transcriptUnavailable: trueflag with nocliSessionIdis a pattern I haven't seen documented before.My guess: those 25 sessions predate the current
.jsonltranscript format. The Desktop is marking them explicitly unavailable rather than just missing a pointer — which to me suggests the app knows no transcript was ever written in the current format, rather than that one existed and got lost. That's a different failure mode from the ones the toolkit handles, where the JSONL exists but the metadata layer lost track of it.Before writing them off — the
completedTurnsfield surviving in the metadata is worth paying attention to. If those sessions show non-zero values, the Desktop was tracking turn activity for them, which may mean there was a storage format before.jsonlthat's now unread. Worth checking%APPDATA%\Claude\for any subdirectory that isn'tclaude-code-sessions\— there may be an older transcript store somewhere.If nothing surfaces there, the toolkit (
claude-code-session-recovery) can confirm the diagnosis but can't recover transcripts that were never written in the current format. The backup guidance in your comment is the right mitigation going forward. Full write-up at #56172.As a work around I have setup Claude Code to backup all my project files every four hours using duplicati, so I have only lost 4 hours work at the most and anything that I want to make sure that I don't lose I use a /backup command to force a backup.
The loss of these projects would only have been with the second or third last update last week as I'm pretty sure they were all there prior to that.
It is just lucky that one of my projects was a project continuation app that created a number of MDs that contained the most important information for each project so I can revive most of the lost projects.
Thanks
John Michelmore
________________________________
From: BasedGPT @.*>
Sent: Wednesday, May 27, 2026 11:37 PM
To: anthropics/claude-code @.*>
Cc: jmichelmore @.>; Comment @.>
Subject: Re: [anthropics/claude-code] Desktop app update deletes session history (sessions-index.json + .jsonl files) (Issue #48334)
[https://avatars.githubusercontent.com/u/131253485?s=20&v=4]BasedGPT left a comment (anthropics/claude-code#48334)<https://github.com/anthropics/claude-code/issues/48334#issuecomment-4555017203>
Hey jmichelmore,
The transcriptUnavailable: true flag with no cliSessionId is a pattern I haven't seen documented before.
My guess: those 25 sessions predate the current .jsonl transcript format. The Desktop is marking them explicitly unavailable rather than just missing a pointer — which to me suggests the app knows no transcript was ever written in the current format, rather than that one existed and got lost. That's a different failure mode from the ones the toolkit handles, where the JSONL exists but the metadata layer lost track of it.
Before writing them off — the completedTurns field surviving in the metadata is worth paying attention to. If those sessions show non-zero values, the Desktop was tracking turn activity for them, which may mean there was a storage format before .jsonl that's now unread. Worth checking %APPDATA%\Claude\ for any subdirectory that isn't claude-code-sessions\ — there may be an older transcript store somewhere.
If nothing surfaces there, the toolkit (claude-code-session-recovery) can confirm the diagnosis but can't recover transcripts that were never written in the current format. The backup guidance in your comment is the right mitigation going forward. Full write-up at #56172<https://github.com/anthropics/claude-code/issues/56172>.
—
Reply to this email directly, view it on GitHub<https://github.com/anthropics/claude-code/issues/48334?email_source=notifications&email_token=AN7HHS4UXMWE3C3PIW5UFK3443VSDA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTINJVGUYDCNZSGAZ2M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-4555017203>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AN7HHS55C55Q6KG4YEMZT2D443VSDAVCNFSM6AAAAACXZZYRW6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DKNJVGAYTOMRQGM>.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS<https://github.com/notifications/mobile/ios/AN7HHSY5WM2OOIUHWNFWXBD443VSDA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTINJVGUYDCNZSGAZ2M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJKTGN5XXIZLSL5UW64Y> and Android<https://github.com/notifications/mobile/android/AN7HHS7PFDGVYN22SMSLNRL443VSDA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTINJVGUYDCNZSGAZ2M4TFMFZW63VHMNXW23LFNZ2KKZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>. Download it today!
You are receiving this because you commented.Message ID: @.***>
Thanks for the quick follow-up and for confirming the behaviour was correct — knowing it was a true unrecoverable state rather than a tool gap actually helps close it out mentally.
Glad the
--statefixture approach transferred cleanly. And while testing, I noticed thatfind_missing_jsonls_in_backup.pywas the only script that didn't receive the native macOS/Linux path detection from commit0609930—diagnose.pyandrepair_session_metadata.pywere both updated but this one was missed. I've submitted a fix: PR #6.I've also written up the full incident — root cause, recovery steps, and the broader lesson about keeping the engineering mindset sharp even when leaning on AI tools — as a blog post if it's useful for anyone landing here from search: When AI Ate My Work: A Claude Code Data Loss Incident
Thanks again for building this. Even a confirmed-unrecoverable result is far better than uncertainty.
You're welcome, glad it helped — just merged the PR fix too, cheers.
That's good to hear — same solution I ended up with. Four-hour window is a reasonable safety net.
If you're on macOS and your
.jsonltranscripts got deleted, I built a tool that restores them from Time Machine or local APFS snapshots: garrettmoss/restore-claude-history. If a backup or snapshot predates the deletion, it'll pull the lost transcripts back.It covers a different piece than @BasedGPT's
claude-code-session-recovery(Windows): his toolkit rebuilds the Desktop metadata so sessions show up again, mine (MacOS) gets the deleted transcript file back.I think this is in line with @rpranjan11's recommendation in his blog post to enable TM backups right away. Here's how to actually use those to recover your chats.
Also filed #62272 on the underlying deletion behavior.
Thanks for building this @garrettmoss — this is exactly the missing piece for Mac users who still have Time Machine or APFS snapshots available.
In my case, unfortunately, neither was set up at the time of the deletion, so the transcripts were unrecoverable. That experience is what pushed me to write about it — both to document the incident and to make sure other engineers don't end up in the same situation.
I wrote two articles covering the full story if it's useful for anyone landing here:
Your tool + @BasedGPT's toolkit together now cover the full recovery surface on macOS. Good to see the ecosystem filling in.