Desktop app: session history list frozen at a fixed date (2026-06-23) while new sessions keep being created
Desktop app: session history list frozen at a fixed date (sessions still created, files intact)
Environment
- Claude Desktop app version: 1.18286.0.0 (Windows 11, MSIX/Store install)
- Claude Code CLI version: 2.1.112
- OS: Windows 11 Home Single Language, 10.0.26200
Summary
The desktop app's session/chat history list stopped showing any session created after 2026-06-23. New sessions continue to be created and used normally, but none of them appear in the history list — it is frozen at the June 23 cutoff. The same cutoff affects the session-management tools (list_sessions / search_session_transcripts both return nothing after 2026-06-23).
Data is NOT lost
All transcript .jsonl files exist and are fully readable at:C:\Users\udayd\.claude\projects\C--Users-udayd-OneDrive-Desktop-claude\
Files dated 2026-06-24 through today are present. This is purely a history-list / indexing display bug, not data loss.
What I verified
- Post-June-23 transcript files are byte-for-byte the same schema as pre-June-23 files (identical top-level and message-record fields: cwd, version, message, sessionId, timestamp, etc.). So it is not a format change or corruption.
- The cutoff is a clean date boundary (everything up to 2026-06-23 shows; nothing after), which points to an indexer/sync cursor that stalled rather than a per-file parse failure.
Steps taken that did NOT fix it
- Fully closed and reopened the desktop app.
- Rebooted the laptop.
Both had no effect — the list resumes from the stalled June 23 cutoff instead of rebuilding the index.
Expected
History list rebuilds from the transcript files on disk and shows all sessions, including those after 2026-06-23.
Actual
History list is permanently frozen at 2026-06-23 despite valid, newer transcript files existing on disk.
Proof - files on disk after the cutoff
Listing of transcript files modified after 2026-06-23 inC:\Users\udayd\.claude\projects\C--Users-udayd-OneDrive-Desktop-claude\\
(none appear in the history list, yet all are valid and readable):
2026-07-05 00:16 d2a078aa-...jsonl
2026-07-05 00:11 e5d9aeab-...jsonl
2026-07-05 00:00 ff0df946-...jsonl
2026-07-04 23:48 724c6845-...jsonl
2026-07-04 23:48 794b7ccb-...jsonl
2026-07-04 23:40 4351880b-...jsonl
2026-07-04 23:38 3ba3730c-...jsonl
2026-07-04 21:12 889b9006-...jsonl
2026-07-04 12:42 38277fd3-...jsonl
2026-07-02 18:08 f27d5e95-...jsonl
2026-07-01 14:10 f27e5b1a-...jsonl
2026-06-30 17:11 5e0a4a3e-...jsonl
2026-06-30 17:04 01ef58f2-...jsonl
2026-06-30 16:58 daa0dede-...jsonl
2026-06-25 16:59 cf4a0a0d-...jsonl
The most recent session shown in the app's history list is dated 2026-06-23; every file above is newer and missing from it.
Showing cached comments. Read the full discussion on GitHub ↗
5 Comments
Root cause identified
I traced this to a broken atomic file-write in the desktop app's session-index writer.
How the history list is built: The desktop app stores one metadata record per session as
local_<id>.jsonunder%APPDATA%\Claude\claude-code-sessions\<accountId>\<orgId>\.The Claude Code history list (and the session-management tools) are built entirely from these records, not from a live scan of the transcript
.jsonlfiles. On startup the log shows:Loaded 26 persisted sessions from ...\claude-code-sessions\....The bug: The app saves each record atomically by writing
local_<id>.json.tmpthen renaming it over the real file. Starting with build 1.18286.0.0, that write fails withEEXISTbecause the temp file is opened with an exclusive-create flag instead of overwriting/cleaning a stale temp:Timeline (from
%APPDATA%\Claude\logs\main.log):Failed to save session ... EEXISTerror: 2026-06-24 15:53:10Because no record can be persisted, the history list is frozen at the last successful save (2026-06-24). New sessions keep running and their transcripts are written normally by the CLI to
~/.claude/projects/**/*.jsonl(a different code path), which is why no chat data is lost.Same faulty writer hits the config file too:
Why only Claude Code, not web/app chat: web chat history is server-side and never touches this local writer; only the local Claude Code index does.
Suggested fix: in
writeSessionToDisk, open the temp file with truncate/overwrite semantics (or unlink any pre-existing.tmpbefore writing, or use a unique temp name per attempt), and clean up the.tmpon error so a single failed write doesn't permanently wedge all future saves.Note: I reinstalled the latest version of the app and the issue still persists.
Environment: Claude Desktop 1.18286.0.0 (Windows 11, MSIX/Store), CLI 2.1.112.
Additional symptom (clearest user-facing description)
The user-visible effect of the failed
writeSessionToDiskis: a session stays in the sidebar only while the app is open; as soon as the app is closed, it disappears.This matches the root cause exactly:
local_<id>.json) fails withEEXIST, so it is never written to disk.The underlying conversation is not lost — the transcript is written separately by the CLI to
~/.claude/projects/**/*.jsonland remains intact; only the app-side session pointer is missing.claude --resume(which reads the transcripts directly) can still list/restore these sessions, but the desktop history UI cannot.Net effect: since 2026-06-24, no new Claude Code session survives an app restart in the desktop history list.
Correction / refinement to my earlier root-cause comments
After going through
%APPDATA%\Claude\logs\main.log(2,269EEXISToccurrences), I need to correct one claim and sharpen two others.Correction: this is NOT a regression introduced in build
1.18286.0.0The same
EEXISTatomic-write failure appears across six app builds in my logs, not just one:| Build |
EEXISTstack lines in main.log ||---|---|
| 1.14271.0.0 | 694 |
| 1.15200.0.0 | 1095 |
| 1.15962.1.0 | 261 |
| 1.17377.1.0 | 508 |
| 1.17377.2.0 | 746 |
| 1.18286.0.0 | 2240 |
So it is a persistent defect across many versions, not a single-build regression. This directly explains why reinstalling the latest version did not fix it — there is no known-good recent build to reinstall to.
Sharpening: the defect is in a shared atomic-write helper, not in
writeSessionToDiskaloneEvery failing write funnels through the same helper (
.vite/build/index.js:81→writeFile→openwith an exclusive-create flag →EEXIST).writeSessionToDiskis just one of at least four callers that all break identically. Distinct.tmptargets hittingEEXIST:manifest.json.tmp(plugin/RPM sync) — 1,856claude_desktop_config.json.tmp— 246local_<sessionId>.json.tmp(the session-index records that build the history sidebar) — 200+ per session idextensions-blocklist.json.tmp— 204Because the broken code is a shared writer, a fix there repairs session history, plugin sync, config saves, and blocklist updates all at once.
Sharpening: EEXIST looks like the primary defect, but the sub-mechanism is still open
The session-index directory holds exactly 26
local_*.jsonrecords, matching the startup logLoaded 26 persisted sessions.writeSessionToDiskdemonstrably fails to add new ones, which is why the sidebar is frozen and newer sessions vanish on restart. Transcripts remain intact (separate CLI write path).One caveat I can't resolve without the source: there are currently zero leftover
*.tmpfiles anywhere under%APPDATA%\Claude. So a simple "a stale.tmpis blocking every future write" story does not fully fit — a race on a fixed temp filename (one writer wins and cleans up, a concurrent writer hitsEEXISTon exclusive-create) fits the observations better. Either way, the suggested fix stands: use a unique temp name per write (or truncate-overwrite) and clean up the.tmpon failure.(Environment: Windows 11 Home, MSIX/Store install, package
Claude_pzs8sxrjxfjjc.)Your post-June-23 sessions are recoverable before any upstream fix lands. The transcripts are intact; what's missing is the metadata records the Desktop uses to build its session list. Those are two separate writes, and the EEXIST bug only broke one of them.
I built a toolkit for exactly this case:
synth_session_metadata.pyinBasedGPT/claude-code-session-recoveryscans~/.claude/projects/for transcript files with no matching entry in%APPDATA%\Claude\claude-code-sessions\and synthesises the metadata files for each one. It derives thecliSessionId,cwd, and timestamps directly from the transcript content — the same schema the Desktop would have written if the atomic save had succeeded.Run
diagnose.pyfrom the same toolkit first. It maps all your transcript files against the metadata directory and shows the full count of orphaned transcripts before anything is written.One path note for the MSIX install:
%APPDATA%\Claude\claude-code-sessions\can resolve to a virtualised location on a Store package. Ifdiagnose.pyreturns an empty metadata directory despite the Desktop having loaded 26 sessions on startup, the real path is likely under%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\claude-code-sessions\— pass that explicitly to both scripts.After running
synth_session_metadata.py, restart Desktop and the sidebar should rebuild from the newly synthesised records. Running it again periodically will catch new sessions until the upstream EEXIST fix lands.Hope this helps, if my tools are able to help you, would appreciate a ⭐ :)
**Update: the history list can be repopulated, but the app's own broken session-save re-prunes it on restart — so new chats keep going invisible.**
Adding concrete evidence from my install (Windows 11, MSIX build 1.18286.2.0, data dir relocated to
D:\Claudevia a directory symlink from%APPDATA%\Claude).The read path works. The history list is built from
%APPDATA%\Claude\claude-code-sessions\<acct>\<org>\local_*.json. Mine was frozen at 6 records while~/.claude/projects/held 27 intact transcripts. After synthesising the missinglocal_*.jsonmetadata for the orphaned transcripts, the app loaded them all —main.log:...and the full history appeared in the sidebar. So the transcripts were never lost — only the metadata index.
But it does not persist. After a normal quit/reopen the folder had degraded 26 → 9:
The cause is the app's session-save failing on every write:
Two things narrow the root cause:
15:31:44,15:32:08,15:34:42), and there are zero.tmpfiles left on disk between attempts — so this is not a stale/orphaned temp file. It's a concurrency race in the shared atomic-write helper: a fixed/deterministic<target>.tmpname created withO_EXCLand no per-target serialisation, so two overlapping writes for the same target collide and the loser throws EEXIST.index.js:81:...) also throws EEXIST forclaude_desktop_config.json.tmpandextensions-blocklist.json.tmpin the same startup, confirming it's a shared writer, not specific to sessions.User impact: because saving new session metadata fails the same way, every chat created after a manual re-sync is also invisible until the folder is rebuilt again — an endless loop. Manually repopulating is not a real fix.
Suggested fix (any one is sufficient):
<target>.tmp.<pid>.<rand>), orO_EXCLflag on the temp create.The EEXIST stacks span at least 6 builds (1.14271 → 1.18286.2.0), so this is long-standing rather than a recent regression, which is why updating to the latest build doesn't help.