[BUG] Windows MSIX/Cowork: in-app Claude Code writes silently virtualized (succeed but don't persist), and in-place updates deadlock on the Cowork VM service's file handles
Summary
When a **Claude Code session runs inside the MSIX-packaged Claude Desktop app on Windows, the session inherits the app's package identity. MSIX write-virtualization then silently redirects the session's writes to %LOCALAPPDATA%, %APPDATA%, and HKCU into the package's virtual store — and because reads are copy-on-write, the same session reads the redirected values back and reports success**. The real machine is never modified. There is no error at any point.
This is distinct from the existing MSIX issues in this repo, which fail loudly (install HRESULTs, Cowork EXDEV rename failures) or concern the read path (MCP config resolved from a virtualized location). This is a silent write-path failure: the session cannot detect it from the inside, and it reports the operation as done.
Impact
Any in-app Claude Code task that:
- installs software to
%LOCALAPPDATA%, - sets autostart (an
HKCU\...\Runvalue, a Startup-folder shortcut, a scheduled task), or - otherwise writes to
HKCU/%APPDATA%/%LOCALAPPDATA%
…succeeds against the package sandbox only. From the session's perspective every write and read-back verification passes. After a reboot (or from any out-of-package process), none of it is present on the real machine. Two operations that "verified live" in-session were both gone after a restart in my case — one autostart entry that was supposed to be added, and one that was supposed to be removed (the removal only tombstoned inside the overlay; the real entry survived).
Repro
- Install Claude Desktop for Windows as the default MSIX build (package family
Claude_pzs8sxrjxfjjc). - Launch a Claude Code session inside the desktop app (so it inherits package identity).
- From that session, write to a real-machine location, e.g.
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" /v Foo /d "C:\some\app.exe" /f
or write a file to %LOCALAPPDATA%\Foo\bar.txt.
- Read it back from the same session — it appears present; the command reports success.
- From an out-of-package process (a normal terminal, or
wmic process call create "cmd /c reg query ..."), query the same key/path — it is absent. The write actually landed in
%LOCALAPPDATA%\Packages\Claude_pzs8sxrjxfjjc\LocalCache\... and the package's private registry hive.
- Reboot → none of the changes are on the real machine.
The copy-on-write read semantics make this especially hard to catch: an in-session read of a path the container hasn't touched falls through to the real machine (looks correct), while a read of a path it has written/deleted shows the overlay (looks correct too). So "read it back to verify" always passes and never reveals the redirect.
Environment
- Windows 11 Home, build 26200 (25H2)
- Claude Desktop MSIX 1.20186.7.0, package family
Claude_pzs8sxrjxfjjc Get-AppxPackage -Name Claude→SignatureKind: Developer,InstallLocation: C:\Program Files\WindowsApps\Claude_1.20186.7.0_x64__pzs8sxrjxfjjc- The package manifest uses flexible virtualization with only a few app-specific exclusions (browser native-messaging-host keys, Office
WEF,LocalAppData\Claude-3p); general-purposeHKCU\...\Runand arbitrary%LOCALAPPDATA%writes are not excluded, so they are virtualized.
Confirmed workaround
Installing the non-MSIX (Squirrel) build instead — winget install Anthropic.Claude (InstallerType exe, per-user, from downloads.claude.ai), or the direct Claude-<hash>.exe from Anthropic's CDN — yields an unvirtualized per-user install at %LOCALAPPDATA%\AnthropicClaude, where in-app Code writes hit the real locations. (This matches #48362, which was resolved the same way.)
Suggested resolution (any of)
- Document this prominently for Claude Code users on Windows — the MSIX build silently no-ops filesystem/registry writes an in-app coding session makes.
- Provide a supported way for in-app Code sessions to run de-virtualized (e.g. spawn the Code toolchain out of the package via the desktop-app breakaway policy
PROC_THREAD_ATTRIBUTE_DESKTOP_APP_POLICY = ENABLE_PROCESS_TREE). - Recommend the Win32/Squirrel install for users who run Claude Code from the desktop app.
---
Second symptom, same MSIX/Cowork root: in-place updates deadlock on the Cowork VM service's file handles
Separately triageable, but it shares the packaging root, so filing together.
Symptom. An auto-update installs, then the app locks up reporting a file in use under C:\Program Files\WindowsApps\Claude_<ver>_x64__pzs8sxrjxfjjc\. Recovered only by a reboot; it has recurred across three consecutive updates on this machine. (While investigating, the user also hit the WindowsApps package folder being inaccessible even to an administrator — that part is expected TrustedInstaller behavior, not corruption, but it compounds the "something is badly wrong" impression during a failed update.)
Root cause. CoworkVMService (runs as localSystem, WIN32_PACKAGED_PROCESS) hosts a Hyper-V/HCS utility VM and holds open file handles on binaries inside the package directory — including ...\app\resources\cowork-svc.exe and the VM bundle. An in-place MSIX update must replace those exact files, but Windows cannot replace a file that is in use → the update deadlocks. A reboot stops the service and tears down the VM, releasing the handles, and the staged update then completes on next launch.
Evidence (C:\ProgramData\Claude\Logs\cowork-service.log, this machine):
- HCS/VM initialization:
[HCS] vmcompute.dll loaded successfully,[HCS] computecore.dll loaded successfully,[HCS] Procs initialized, HCS ready. - Service binary path:
[Server] Service: C:\Program Files\WindowsApps\Claude_1.20186.7.0_x64__pzs8sxrjxfjjc\app\resources\cowork-svc.exe. - A VM session is created on app launch:
[Server] Created new VM session for DM:...immediately followed by[IdleCheck] ... starting idle timer now.
Notable — this hits users who never use Cowork. The reporting user has never intentionally invoked Cowork, yet CoworkVMService auto-starts and opens a VM session on every app launch, so the update-lock is not gated on actual Cowork usage.
Suggested resolution (any of).
- Have the updater stop
CoworkVMServiceand quiesce its VM before replacing packaged files. - Don't auto-start / auto-open a VM session when Cowork is unused, so idle installs don't hold package handles.
- As above, the Win32/Squirrel build sidesteps this entirely (per-user install, no
WindowsApps, no packaged VM service to lock).
Same convergence as the write-virtualization symptom: the Cowork packaged VM service is the common thread behind both.
Related (not duplicates)
- #48362 (closed) — Code sessions silently fail to persist via
EXDEVinside MSIX, resolved by switching to the Win32 installer. Same root cause, loud (EXDEV) symptom; this report is the silent write-redirect variant. - #70393, #26073 — MSIX-virtualized read path for MCP config.
- #68070 — MSIX fails to launch where the Squirrel/winget build works on the same machine.
- #76980 — Squirrel→MSIX migration orphans Start-Menu/desktop shortcuts (adjacent: stale shortcuts pointing into the sandbox).
- #65887 —
CoworkVMServicestops between sessions and cannot be restarted by the app (update-lock section). - #55946 — MSIX 3P mode:
rootfs.vhdxcommit fails, app self-terminates (update-lock section). - #36440, #76982 — Cowork
EXDEVcross-device link failures under MSIX virtualization (update-lock section).
4 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
I hit a very similar class of problem on Windows while wiring a local CLI/agent setup from inside Claude Desktop: the tool reported that config/hook files were written, and the same session could read them back, but a normal terminal/new session did not see the expected machine state.
The most useful diagnostic for me was to verify from outside the MSIX/app context, not from the same session that performed the write:
For any installer/config writer, I’d suggest making the post-write verification use a fresh external process or documenting that verification from the same app identity is not sufficient. Otherwise it creates a very confusing “success but nothing changed” user experience.
Temporary workaround that helped me: perform config/hook writes from a normal terminal session, then restart Claude Desktop/Claude Code and verify from another fresh terminal.
Narrowing this report (apologies for bundling two bugs into one — should have been separate).
The update-deadlock symptom here —
CoworkVMService/cowork-svc.exeholding package file handles so an in-place MSIX update fails with "another program is currently using this file" — is already tracked, and more precisely, in #73694 and #76357. Those should be treated as canonical for that symptom.I'd like to keep this issue focused on the other, less-tracked half: silent filesystem/registry write-virtualization for Claude Code sessions running inside the MSIX app. Writes to
%LOCALAPPDATA%/%APPDATA%/HKCUare redirected into the package sandbox, and because reads are copy-on-write, the same session reads them back and reports success — so config / hook / install writes silently no-op against the real machine, with no error at any point.@PsYcGoD reproduced exactly this above (in-app write reports success; a fresh external session sees no change).
This is distinct from #48362 (closed): that was the loud failure (
EXDEVcross-device error); this one is silent — the write "succeeds" into the overlay and only a process outside the package identity reveals that the real machine never changed. As @PsYcGoD notes, the reliable diagnostic is to verify from an external process, never from the same in-app session.Repro and environment are in the original post (Windows 11 build 26200, MSIX 1.20186.7.0, package family
Claude_…_pzs8sxrjxfjjc). Fix options: exclude common developer-write locations from virtualization, give in-app Code sessions a de-virtualized execution path, or — as the practical workaround — recommend the non-MSIX / Squirrel build for Claude Code users, which resolves it entirely (confirmed on my end).@UnAccordStudios
Thanks for narrowing it. Yes, that matches what I saw: same-session verification can be misleading because it reads back from the virtualized view. External-process verification was the only reliable way to confirm whether the real machine changed.