Cowork VM SDK install on Windows ARM64: hundreds of Operation not permitted errors during node_modules cleanup

Resolved 💬 1 comment Opened Apr 26, 2026 by Xare123 Closed May 29, 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 VM SDK install on Windows ARM64: hundreds of Operation not permitted errors during node_modules cleanup

Environment

  • OS: Windows 11 ARM64 (Snapdragon Lenovo laptop)
  • Claude Desktop: 1.4758.0.0 (arm64 MSIX, installed from Microsoft Store)
  • Update channel: https://api.anthropic.com/api/desktop/win32/arm64/msix/update
  • Cowork SDK version: 2.1.119
  • Cowork install path: C:\Users\<user>\AppData\Roaming\Claude\claude-code-vm\2.1.119\
  • Log file: %APPDATA%\Claude\logs\cowork_vm_node.log

What's wrong

Every time the Cowork VM starts up, the SDK refresh step shells out to bash and runs rm against the existing node_modules directory before laying down the new SDK copy. On Windows ARM64 that rm fails for 384 files in a single startup, all with the same error: Operation not permitted. Cowork keeps running afterwards, but:

  • The cleanup never actually completes — old SDK files are left behind on disk.
  • The log gets spammed with hundreds of identical [warn] lines per startup, drowning out real warnings.
  • Stale modules accumulate over time. Eventually a file from an old SDK version may be resolved instead of the new one, causing hard-to-debug MODULE_NOT_FOUND or version-mismatch failures.

What Should Happen?

What should happen

Starting the Cowork VM should produce a clean SDK install:

  • Old node_modules files are removed cleanly before the new SDK is laid down.
  • The log shows a normal install sequence with no Operation not permitted warnings.
  • No stale files remain in claude-code-vm\<version>\node_modules\.

Error Messages/Logs

**Stats from one startup:**
- Total `Operation not permitted` warnings: **384**
- Distinct top-level `node_modules` directories affected: **24**
  - `.bin`, `.package-lock.json`, `@types`, `core-util-is`, `docx`, `hash.js`, `immediate`, `inherits`, `isarray`, `jszip`, `lie`, `minimalistic-assert`, `nanoid`, `pako`, `process-nextick-args`, `readable-stream`, `safe-buffer`, `sax`, `setimmediate`, `string_decoder`, `undici-types`, `util-deprecate`, `xml`, `xml-js`
- Files affected include type declarations, license/readme files, top-level entry scripts, and the package's own `package.json`.

**Representative excerpt** (errors fire immediately after the bash one-shot launches):


2026-04-25 05:29:15 [info] [vmOneShot] Running: bash [2 arg(s)] as brave-nifty-einstein
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/.bin/nanoid': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/.bin/xml-js': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/.package-lock.json': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/@types/node/assert/strict.d.ts': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/@types/node/assert.d.ts': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/@types/node/async_hooks.d.ts': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/@types/node/buffer.buffer.d.ts': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/@types/node/buffer.d.ts': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/@types/node/child_process.d.ts': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'node_modules/@types/node/cluster.d.ts': Operation not permitted
... (374 more identical-pattern lines) ...
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'package.json': Operation not permitted
2026-04-25 05:29:15 [warn] [vm-stderr oneshot-] rm: cannot remove 'package-lock.json': Operation not permitted


**After the failed cleanup, normal operation continues:**


2026-04-25 06:51:50 [info] [startVM] VM already connected
2026-04-25 06:51:50 [info] [postConnect] Installing SDK: subpath=c/Users/<user>/AppData/Roaming/Claude/claude-code-vm, version=2.1.119
2026-04-25 06:51:52 [warn] [Keepalive] Already running


The `[Keepalive] Already running` warning suggests the previous Cowork VM process is still alive when `rm` runs — a likely contributor to the file-locking failures.

Steps to Reproduce

Steps to reproduce

  1. Use a Windows 11 ARM64 device (Snapdragon — e.g. Lenovo with X Elite/Plus).
  2. Install Claude Desktop from the Microsoft Store (arm64 MSIX, version 1.4758.0.0 or later).
  3. Sign in and enable Cowork mode in settings.
  4. Open any Cowork session — the SDK install runs on first connection and again on every subsequent startup that detects a version delta.
  5. Open %APPDATA%\Claude\logs\cowork_vm_node.log in any text editor.
  6. Search for the string Operation not permitted. You will see hundreds of matches, all generated within the same second by a single [vmOneShot] Running: bash invocation.

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.119

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

WSL (Windows Subsystem for Linux)

Additional Information

Likely cause

The Cowork sandbox appears to run a Linux userland on top of the Windows host filesystem (the SDK target path c/Users/<user>/AppData/Roaming/Claude/claude-code-vm is a Linux-style mount of the Windows path). Linux rm relies on POSIX unlink semantics, which work fine on files held open by other processes. NTFS does not — if a file is held open without FILE_SHARE_DELETE, unlink fails with EPERM (Operation not permitted).

Candidate processes holding handles on these files at refresh time:

  • A long-running node worker inside the sandbox itself (the [Keepalive] Already running log line immediately after the failures suggests the previous VM process is still up).
  • Windows Defender / MsMpEng scanning newly written files.
  • Any third-party antivirus or endpoint protection.

The fact that the failures hit dozens of unrelated packages in one sweep — including read-only .d.ts files that nothing should be writing to — points more at a filesystem-semantics mismatch than at a real lock-holder.

Suggested fixes

  1. Stop the previous Cowork VM process (and its worker tree) before running the cleanup, not after — current order looks like the keepalive process is still alive when rm runs.
  2. Fall back to a Windows-aware delete (MoveFileEx ... MOVEFILE_DELAY_UNTIL_REBOOT for files that can't be unlinked, or shell out to PowerShell Remove-Item -Force -Recurse, which uses CreateFile with FILE_SHARE_DELETE).
  3. Use content-addressed install dirs (claude-code-vm/<version>/<sha>) so refreshes never need to delete anything — just create a new dir and update a symlink.
  4. At minimum, suppress the per-file warnings and emit one summary line rm: failed to clean N of M files in <path> so the log stays useful.

Anything else

Happy to provide the full cowork_vm_node.log (~90 KB), main.log, or run any diagnostic commands. Chrome MCP and the rest of Claude Desktop are working fine — this is isolated to the Cowork SDK install/refresh path.

cowork_vm_node.log

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗