claude-code - 💡(How to fix) Fix [BUG] MSIX: Code sessions lost on restart — EXDEV error in session save (fs.rename across VFS reparse point) [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#46881Fetched 2026-04-12 13:30:35
View on GitHub
Comments
2
Participants
2
Timeline
6
Reactions
1
Timeline (top)
labeled ×4commented ×2

Error Message

[error] Failed to save session local_c6493c1e-...: EXDEV: cross-device link not permitted, Then we checked main.log and found thousands of EXDEV errors. The .json.tmp.json rename was failing silently from the user's perspective (no UI error), but every session save was broken. [warn] [marketplaceFileOps] rename(...manifest.json.tmp → ...manifest.json) failed (EXDEV), After running this, Desktop loads all sessions normally on next start. But new sessions will hit the same EXDEV error, so the script needs to be re-run periodically.

Root Cause

Root cause: EXDEV on MSIX — fs.rename() fails across VFS reparse point

Fix Action

Workaround

A simple script that copies .json.tmp.json while Desktop is closed restores all sessions:

// For each local_*.json.tmp without a corresponding .json:
await fs.copyFile(tmpPath, jsonPath);  // copyFile works cross-device, rename doesn't

After running this, Desktop loads all sessions normally on next start. But new sessions will hit the same EXDEV error, so the script needs to be re-run periodically.

Code Example

[error] Failed to save session local_c6493c1e-...: EXDEV: cross-device link not permitted, 
  rename '...claude-code-sessions\...\local_c6493c1e-....json.tmp' 
      -> '...claude-code-sessions\...\local_c6493c1e-....json'

---

[warn] [marketplaceFileOps] rename(...manifest.json.tmp...manifest.json) failed (EXDEV), 
  falling back to direct write

---

// For each local_*.json.tmp without a corresponding .json:
await fs.copyFile(tmpPath, jsonPath);  // copyFile works cross-device, rename doesn't

---

try {
  await fs.rename(tmpPath, finalPath);
} catch (err) {
  if (err.code === 'EXDEV') {
    await fs.copyFile(tmpPath, finalPath);
    await fs.unlink(tmpPath);
  } else {
    throw err;
  }
}
RAW_BUFFERClick to expand / collapse

Bug description

Code sessions in Claude Desktop disappear from the sidebar after every restart or app update. Sessions work fine during the current run but are gone when Desktop is reopened.

Environment: Windows 11, Claude Desktop 1.1617.0 (MSIX package)

Root cause: EXDEV on MSIX — fs.rename() fails across VFS reparse point

On Windows, Claude Desktop is installed as an MSIX package (Claude_pzs8sxrjxfjjc). The %APPDATA%\Claude path is a VFS reparse point that resolves to D:\WpSystem\<SID>\...\LocalCache\Roaming\Claude — a different drive letter than C:.

When Desktop saves Code session metadata, it uses the standard atomic write pattern: write to .json.tmp, then fs.rename('.json.tmp', '.json'). The rename fails with EXDEV: cross-device link not permitted because the OS sees the VFS reparse as a cross-device operation.

From main.log (first occurrence, day 1 of install):

[error] Failed to save session local_c6493c1e-...: EXDEV: cross-device link not permitted, 
  rename '...claude-code-sessions\...\local_c6493c1e-....json.tmp' 
      -> '...claude-code-sessions\...\local_c6493c1e-....json'

3,796 EXDEV errors in my log since March 25. Every single session save fails. Sessions stay as .json.tmp and are never finalized to .json, so they're lost on restart.

How we found it

We initially assumed the issue was LevelDB — wrote a script to inject LSS-cc-* keys directly into Local Storage/leveldb. That didn't work: Desktop cleans up unrecognized keys on restart during compaction.

Then we checked main.log and found thousands of EXDEV errors. The .json.tmp.json rename was failing silently from the user's perspective (no UI error), but every session save was broken.

Proof that the fix pattern already exists in the codebase

Interestingly, the marketplaceFileOps module already handles EXDEV with a fallback:

[warn] [marketplaceFileOps] rename(...manifest.json.tmp → ...manifest.json) failed (EXDEV), 
  falling back to direct write

The session save code just needs the same fallback: catch EXDEV, fall back to fs.copyFile() + fs.unlink() (or direct write).

Workaround

A simple script that copies .json.tmp.json while Desktop is closed restores all sessions:

// For each local_*.json.tmp without a corresponding .json:
await fs.copyFile(tmpPath, jsonPath);  // copyFile works cross-device, rename doesn't

After running this, Desktop loads all sessions normally on next start. But new sessions will hit the same EXDEV error, so the script needs to be re-run periodically.

Suggested fix

Apply the same EXDEV fallback from marketplaceFileOps to the session save code path:

try {
  await fs.rename(tmpPath, finalPath);
} catch (err) {
  if (err.code === 'EXDEV') {
    await fs.copyFile(tmpPath, finalPath);
    await fs.unlink(tmpPath);
  } else {
    throw err;
  }
}

This would fix it for all MSIX installations where the VFS reparse point crosses drive letters.

Related closed issues

  • #29172 — Sessions disappear after restart
  • #29373 — Update loses history in directory migration
  • #25579 — MSIX uses wrong userData path
  • #26758 — MSIX VFS breaks Cowork streaming
  • #31787 — Sessions disappear (VS Code + Desktop conflict)

extent analysis

TL;DR

Apply the EXDEV fallback from marketplaceFileOps to the session save code path to fix the issue with code sessions disappearing after restart or app update.

Guidance

  • Identify the session save code path and apply a try-catch block to handle the EXDEV error.
  • In the catch block, use fs.copyFile() and fs.unlink() as a fallback to handle cross-device operations.
  • Verify that the fix works by checking the main.log for EXDEV errors and ensuring that sessions are persisted after restart or app update.
  • Consider running the provided workaround script periodically to restore sessions until the fix is fully implemented.

Example

try {
  await fs.rename(tmpPath, finalPath);
} catch (err) {
  if (err.code === 'EXDEV') {
    await fs.copyFile(tmpPath, finalPath);
    await fs.unlink(tmpPath);
  } else {
    throw err;
  }
}

Notes

The fix should be applied to the session save code path to handle the EXDEV error that occurs when the VFS reparse point crosses drive letters. The provided workaround script can be used to restore sessions until the fix is fully implemented.

Recommendation

Apply the workaround by implementing the EXDEV fallback in the session save code path, as it is a proven solution that already exists in the marketplaceFileOps module. This will fix the issue for all MSIX installations where the VFS reparse point crosses drive letters.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING