[BUG] Windows: EXDEV error when saving sessions - MSIX VFS rename fails

Resolved 💬 3 comments Opened May 9, 2026 by kelvinwykkk-afk Closed May 12, 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?

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

  1. Install Claude desktop on Windows (official download, MSIX format)
  2. Open the app and start a conversation
  3. Close the app completely
  4. Reopen the app
  5. 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

  1. Install Claude desktop on Windows (official download, MSIX format)
  2. Open the app and start a conversation
  3. Close the app completely
  4. Reopen the app
  5. 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

  1. Create a new session on claude code desktop
  2. exit claude code desktop
  3. 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_

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗