[BUG] Windows: EXDEV error when saving sessions - MSIX VFS rename fails
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?
Windows MSIX: writeSessionToDisk fails with EXDEV, sessions lost on restart
Bug Description
On Windows, the Claude desktop app is distributed as an MSIX package. Due to MSIX filesystem virtualization (VFS), fs.rename() calls within writeSessionToDisk fail with EXDEV: cross-device link not permitted, even though both source and destination paths appear to be in the same directory.
As a result, session files are never finalized from .json.tmp to .json. The "Recent" sidebar loses all conversation history every time the app is restarted.
Root Cause
MSIX VFS maps %APPDATA%\Claude\ to a virtualized path under:
%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\
Node.js fs.promises.rename() cannot perform an atomic rename across the VFS boundary, triggering EXDEV (errno -4037).
Notably, marketplaceFileOps already handles this correctly with a copy+delete fallback:
[warn] [marketplaceFileOps] rename(...) crossed device boundary (EXDEV), falling back to copy+delete
But writeSessionToDisk does not have this fallback and fails hard:
[error] Failed to save session local_xxx: EXDEV: cross-device link not permitted, rename '...local_xxx.json.tmp' -> '...local_xxx.json'
Suggested Fix
Apply the same EXDEV fallback pattern from marketplaceFileOps to writeSessionToDisk:
async function safeRename(src, dest) {
try {
await fs.promises.rename(src, dest);
} catch (err) {
if (err.code === 'EXDEV') {
await fs.promises.copyFile(src, dest);
await fs.promises.unlink(src);
} else {
throw err;
}
}
}
Environment
- OS: Windows 11 Home China 10.0.26100
- Claude Desktop: 1.6608.2.0 (MSIX package:
Claude_pzs8sxrjxfjjc) - Install location:
C:\Program Files\WindowsApps\Claude_1.6608.2.0_x64__pzs8sxrjxfjjc\ - App data (real):
%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\ - App data (VFS):
%APPDATA%\Claude\
Reproduction Steps
- Install Claude desktop on Windows (official download, MSIX format)
- Open the app and start a conversation
- Close the app completely
- Reopen the app
- Observe: the "Recent" sidebar is empty, previous sessions are gone
Evidence
Session directory contains orphaned .json.tmp files that were never renamed:
claude-code-sessions\...\local_xxx.json.tmp (41158 bytes, latest)
claude-code-sessions\...\local_xxx.json (40664 bytes, stale)
Error log (%APPDATA%\Claude\logs\main.log):
[error] Failed to save session local_dc41e0d5-...: EXDEV: cross-device link not permitted,
rename '...\local_dc41e0d5-....json.tmp' -> '...\local_dc41e0d5-....json'
at async Object.rename (node:internal/fs/promises:785:10)
at async hE.writeSessionToDisk (...)
Contrast with the working fallback in marketplaceFileOps:
[warn] [marketplaceFileOps] rename(...) crossed device boundary (EXDEV), falling back to copy+delete
Impact
- All local conversation history is effectively lost on every app restart
- Affects all Windows users running the MSIX-packaged version (which is the only official distribution for Windows)
What Should Happen?
Windows MSIX: writeSessionToDisk fails with EXDEV, sessions lost on restart
Bug Description
On Windows, the Claude desktop app is distributed as an MSIX package. Due to MSIX filesystem virtualization (VFS), fs.rename() calls within writeSessionToDisk fail with EXDEV: cross-device link not permitted, even though both source and destination paths appear to be in the same directory.
As a result, session files are never finalized from .json.tmp to .json. The "Recent" sidebar loses all conversation history every time the app is restarted.
Root Cause
MSIX VFS maps %APPDATA%\Claude\ to a virtualized path under:
%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\
Node.js fs.promises.rename() cannot perform an atomic rename across the VFS boundary, triggering EXDEV (errno -4037).
Notably, marketplaceFileOps already handles this correctly with a copy+delete fallback:
[warn] [marketplaceFileOps] rename(...) crossed device boundary (EXDEV), falling back to copy+delete
But writeSessionToDisk does not have this fallback and fails hard:
[error] Failed to save session local_xxx: EXDEV: cross-device link not permitted, rename '...local_xxx.json.tmp' -> '...local_xxx.json'
Suggested Fix
Apply the same EXDEV fallback pattern from marketplaceFileOps to writeSessionToDisk:
async function safeRename(src, dest) {
try {
await fs.promises.rename(src, dest);
} catch (err) {
if (err.code === 'EXDEV') {
await fs.promises.copyFile(src, dest);
await fs.promises.unlink(src);
} else {
throw err;
}
}
}
Environment
- OS: Windows 11 Home China 10.0.26100
- Claude Desktop: 1.6608.2.0 (MSIX package:
Claude_pzs8sxrjxfjjc) - Install location:
C:\Program Files\WindowsApps\Claude_1.6608.2.0_x64__pzs8sxrjxfjjc\ - App data (real):
%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\ - App data (VFS):
%APPDATA%\Claude\
Reproduction Steps
- Install Claude desktop on Windows (official download, MSIX format)
- Open the app and start a conversation
- Close the app completely
- Reopen the app
- Observe: the "Recent" sidebar is empty, previous sessions are gone
Evidence
Session directory contains orphaned .json.tmp files that were never renamed:
claude-code-sessions\...\local_xxx.json.tmp (41158 bytes, latest)
claude-code-sessions\...\local_xxx.json (40664 bytes, stale)
Error log (%APPDATA%\Claude\logs\main.log):
[error] Failed to save session local_dc41e0d5-...: EXDEV: cross-device link not permitted,
rename '...\local_dc41e0d5-....json.tmp' -> '...\local_dc41e0d5-....json'
at async Object.rename (node:internal/fs/promises:785:10)
at async hE.writeSessionToDisk (...)
Contrast with the working fallback in marketplaceFileOps:
[warn] [marketplaceFileOps] rename(...) crossed device boundary (EXDEV), falling back to copy+delete
Impact
- All local conversation history is effectively lost on every app restart
- Affects all Windows users running the MSIX-packaged version (which is the only official distribution for Windows)
Error Messages/Logs
Steps to Reproduce
- Create a new session on claude code desktop
- exit claude code desktop
- restart claude code desktop
and you will find there is no historic sessions in recent area.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
v1.6608.2.0
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗