[BUG] Cowork EXDEV: cross-device link not permitted on Windows 11 PRO— root cause identified as luafv filesystem filter + AppData virtualization split

Resolved 💬 4 comments Opened Mar 25, 2026 by snasser117 Closed May 25, 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?

Cowork fails to initialize on Windows with the following error every time:
EXDEV: cross-device link not permitted, rename
'C:\Users\XXX\AppData\Roaming\Claude\tmp\wvm-XXXXXX\rootfs.vhdx' ->
'C:\Users\XXX\AppData\Roaming\Claude\vm_bundles\claudevm.bundle\rootfs.vhdx'

After extensive diagnostics (5+ hours of troubleshooting), the root cause has been identified: the tmp folder is treated as a different logical device than vm_bundles by the Windows filesystem stack due to the luafv (UAC File Virtualization) filter driver combined with third-party processes sandboxing inside tmp (Adobe Acrobat, OneDrive, Steam, Edge WebView2). Node.js's fs.rename() sees a junction/virtualization boundary between tmp and vm_bundles and throws EXDEV, even though both paths physically reside on the same C:\ volume.

rootfs.vhdx downloads successfully into tmp\wvm-XXXXXX\ but is immediately deleted when the rename fails. The error repeats every retry attempt. Cowork never initializes.vm_bundles is never created , Claude cannot get past the rename step.
Virtualization is fully functional. The EXDEV error is unrelated to Hyper-V.
CoworkVMService: Present and startable. Never reaches start because rootfs.vhdx rename fails first.

fsutil confirming both paths are on the same physical volume:
AppData root: C:\
tmp volume: C:\
Total bytes: 997,587,939,328 (929.1 GB) ← identical for both paths
fltMC output (relevant drivers):
bindflt 409800 ← MSIX bind filter
luafv 135000 ← UAC File Virtualization (PRIMARY CAUSE)
wcifs 189900 ← Windows Container Isolation
CldFlt 180451 ← Cloud Files (OneDrive)
WdFilter 328010 ← Windows Defender

The following were all attempted without success:

  • Rebooting (multiple times)
  • Reinstalling Claude Desktop (MSIX and non-MSIX)
  • Enabling all Hyper-V features
  • Creating NTFS junction points between tmp and vm_bundles
  • Overriding $env:APPDATA to a plain C:\ path
  • Launching Claude as Administrator
  • Adding Windows Defender exclusions for Claude paths and .vhdx extension
  • Stopping CoworkVMService before launch
  • Using robocopy /MIR to wipe locked tmp contents
  • Safe Mode deletion of vm_bundles folder
  • Removing PendingFileRenameOperations registry entry

Claude Desktop version | 1.1.8308 (2498e4) — also reproduced on 1.1.7714
Install type | Non-MSIX direct .exe installer from claude.ai/download
OS | Windows 11 Pro

What Should Happen?

Cowork should detect that rootfs.vhdx is staged in tmp and complete the move to vm_bundles successfully, initializing the workspace VM. The rename should not fail on a system where both paths are on the same physical C:\ volume.

Error Messages/Logs

Steps to Reproduce

  1. Install Claude Desktop (latest) from claude.ai/download on Windows 11 Pro
  2. Open Claude Desktop and navigate to the Cowork tab
  3. Accept the prompt to download the workspace VM
  4. Wait approximately 1–2 minutes
  5. Observe EXDEV error — rootfs.vhdx is downloaded to tmp\wvm-XXXXXX\ but the rename to vm_bundles\claudevm.bundle\ fails

Claude Model

Other

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

1.1.8308

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

PowerShell

Additional Information

Suggested Fix:

The fix should be implemented in Claude Desktop, not required of users:

Option A (preferred): Replace fs.rename() with a copy-then-delete fallback when the initial rename throws EXDEV. This is standard practice for cross-device moves:
javascripttry {
await fs.rename(src, dest);
} catch (err) {
if (err.code === 'EXDEV') {
await fs.copyFile(src, dest);
await fs.unlink(src);
} else {
throw err;
}
}
Option B: Download rootfs.vhdx directly into vm_bundles\claudevm.bundle\ rather than staging in tmp and renaming. This eliminates the cross-directory move entirely.
Option C: Use a staging directory that is a subdirectory of vm_bundles itself (e.g. vm_bundles\.tmp\) so the rename is always within the same directory tree.

View original on GitHub ↗

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