anthropics / anthropics/claude-code
[BUG] Cowork VM orphaned across sessions (4 GB, macOS) — three kernel panics, logs attached
- 主要言語
- Python
- スター
- 145k
- フォーク
- 23.1k
- PR マージ指標
- PR 指標を取得中
説明
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) 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?
Orphaned Cowork VM holds 4 GB across sessions
Claude Desktop's Cowork workspace VM is stopped only on application quit. Abandoned sessions leave it resident for 17–23 hours on a 16 GB machine, and the app's own memory governor will not evict it under critical pressure. Three kernel panics, all with the same fingerprint.
- Hardware
- MacBook Pro, M1 Pro, 16 GB
- macOS
- 15.7.3 (24G419)
- Claude Desktop
- 1.46388.4
- Electron / Node
- 42.10.0 / 24.18.1
- Panics observed
- 3 — 29 Aug, 30 Aug, 7 Sep 2026
- Panicked task
- com.apple.Virtualization.Virtual…
Summary
Every panic reported the compressed-page limit at 100% with 23, 28 and 39 swap files respectively. The most recent named pid 32911: com.apple.Virtualization.Virtual as the panicked task — the 31-character truncation of com.apple.Virtualization.VirtualMachine, the Virtualization.framework XPC service that hosts Claude's Cowork VM. Activity Monitor names that process Virtual Machine Service for Claude.
The user was not knowingly running any VM. No Docker, UTM, VirtualBuddy or Colima instance was running; Colima is installed but was last active on 29 May 2026, three months before the first panic.
The defect
The VM is stopped only by application quit
Across six weeks of cowork_vm_swift.log, every shutdown carries the same flag. There is no instance of the VM stopping because a session ended, went idle, or was abandoned.
[VM] 2026-09-06 15:39:52 [info] Stopping VM (isAppQuit: true)...~/Library/Logs/Claude/cowork_vm_swift.log — the only shutdown path present in the log.
[VM] 2026-09-06 15:39:53 [info] Guest did stop
[VM] 2026-09-06 15:39:53 [info] VM stopped successfully
The host process is also reparented to launchd, so it is structurally able to outlive whatever created it:
PID PPID RSS ELAPSED COMMAND
3257 1 104576 18:19 /System/Library/Frameworks/Virtualization.framework/
Versions/A/XPCServices/
com.apple.Virtualization.VirtualMachine.xpc/
Contents/MacOS/com.apple.Virtualization.VirtualMachine
ps -Ao pid,ppid,rss,etime,command — parent is PID 1, not the Claude app (PID 943).The allocation is a flat 4 GB regardless of host RAM
All ~50 startVM lines since 30 July request the same figure. On this 16 GB machine that is a quarter of physical memory, permanently committed for as long as the VM lives.
[VM] 2026-09-07 18:42:09 [info] startVM called forGuest confirms it:
~/Library/Application Support/Claude/vm_bundles/claudevm.bundle
with memoryGB=4 cpuCount=auto networkMode=gvisor
[VM] 2026-09-07 18:42:09 [info] - CPUs: 4
[VM] 2026-09-07 18:42:09 [info] - Memory: 4GB
MemTotal: 4000488 kB, 4 vCPU, no guest swap, Ubuntu 22.04 / kernel 6.8.0-136 aarch64.The memory governor cannot evict it
Six minutes before the third panic, Claude's own governor detected critical pressure and found nothing in its eviction set. The 4 GB VM is not a candidate.
14:41:20 [process-memory] tree_footprint_sum=1375MB~/Library/Logs/Claude/main.log — 14 MB free of 16,384 MB.
sys_free=175MB/16384MB sys_free_raw=14MB
14:41:29 [warn] [event-loop-stall] main process blocked for 3980ms
14:41:35 [warn] [CliGovernor] memory pressure (critical): evicted 0 of 0 idle
session(s), 0 effective
14:41:36 [process-memory] sys_free=196MB/16384MB sys_free_raw=15MB
Attaching a cloud session starts the local VM
The VM was launched at 18:42:09, roughly five seconds before the first bridge call of a remote session, and before any shell command had been requested. A session that never runs a local command still pays the 4 GB.
The bridge also holds a power assertion — [remote-tools-device] keep-awake held — so an attached session prevents the machine from sleeping, and the VM never gets a natural teardown.
Three panics, one fingerprint
The Claude log shows exactly three abrupt terminations in six weeks — no beforeQuit, no willQuit, the log simply stops mid-stream. They correspond to the three panics, and each has a long-resident VM behind it.
# | Panic (UK) | Claude log stops | Silent gap | Machine back up | VM started | VM resident at panic
-- | -- | -- | -- | -- | -- | --
1 | 29 Aug 11:43 | 29 Aug 11:40:42 | 2 m 18 s | 12:07:54 | 28 Aug 18:25 | 17 h 17 m
2 | 30 Aug 11:07 | 30 Aug 11:03:18 | 3 m 42 s | 13:02:17 | 29 Aug 12:09 | 22 h 58 m
3 | 7 Sep 14:47 | 7 Sep 14:43:32 | 3 m 28 s | 18:28:54 | 6 Sep 21:05 | 17 h 42 m
Panic times are as reported by the user; log timings are from the files. The 2–4 minute silent gap ahead of each panic is consistent across all three — the last buffered flush reaching disk before the machine could no longer write.
For contrast, an orderly quit on 28 August logs beforeQuit: handler fired, going down followed by willQuit, then Stopping VM (isAppQuit: true). None of the three above do.
What actually triggered the panic
The VM was the precondition; remote screen capture was the trigger
All three panics occurred while the Mac was being captured remotely by RustDesk 1.4.9 over a self-hosted Tailscale relay. RustDesk's own log for the third panic opens the session at 14:40:17 and records the machine as already exhausted before it did anything:
14:40:18 new video service: monitor0~/Library/Logs/RustDesk/server/RustDesk_r2026-09-07_14-40-17.log. Panic followed at ~14:47.
14:40:18 #displays=3, current=0, width=1920, height=1200, cpus=8/8
14:40:18 connection count: 1, used preference: Auto, encoder: AV1
14:40:18 cpu num: 8, cpu loadavg: 4.78, available memory: 0G, codec thread: 1
14:40:31 #displays=3, current=1, origin: (-5240, -993), width=3440, height=1440
14:40:32 new encoder: AOM(AomEncoderConfig { width: 3440, height: 1440, quality: 0.67 })
14:40:32 cpu num: 8, cpu loadavg: 9.06, available memory: 0G, codec thread: 1
RustDesk's hardware-codec config on this machine registers decoders only — ram_encode: [] — so screen capture falls back to the libaom AV1 software encoder, here at 3440×1440. That is an expensive trigger. But it arrived at a machine that already had 0 GB available, and 4 GB of what was gone belonged to a Claude VM that had been idle since the previous evening.
The reading offered here: the VM does not cause the panic, it removes the headroom that would let the machine survive one. It is named as the panicked task because it is the largest single owner of anonymous pages being faulted through an exhausted compressor. Treat the trigger attribution as a hypothesis; the residency data above is directly evidenced.
Suggested fixes
Stop the VM when its last session detaches
An idle timeout — even a generous one — would have prevented all three incidents. Seventeen to twenty-three hours of residency with no attached work is the whole defect.
Put the VM in CliGovernor's eviction set
Logging critical pressure while holding a 4 GB evictable guest and reporting "0 of 0 idle sessions" is the governor missing the largest thing it controls.
Scale memoryGB to host RAM
A flat 4 GB is 12.5% of a 32 GB machine and 25% of a 16 GB one. The same constant is used on both.
Start the VM lazily
Boot it on the first request that actually needs a local shell, not on session attach. Sessions that only use computer-use or file tools never need it.
Release the keep-awake assertion when idle
Holding a power assertion for an attached-but-idle session keeps the machine awake indefinitely, which is what allows a VM to accumulate a 23-hour residency in the first place.
Ruled out
Colima, Docker, UTM, QEMU, Lima
No qemu, lima or colima process existed at inspection. A Colima profile is present on disk at ~/.colima/_lima/colima/ with a 20 GB image, but its most recently modified file is dated 2026-05-29 17:49 UTC — 92 days before the first panic. No other consumer of Virtualization.framework was found on the machine.
Method. Live inspection of the machine: process table and Activity Monitor process inspector for the host side; a shell inside the guest for its kernel, RAM and virtualization type; direct reads of ~/Library/Logs/Claude/{main,cowork_vm_swift}.log and ~/Library/Logs/RustDesk/. No files were modified and no processes terminated during the investigation.
Claim labels. Confirmed statements are direct observations with the evidence shown. Inferred statements are reasoning over that evidence and may be wrong. All times are Europe/London.
### What Should Happen?
Claude should not cause my macbook pro to crash due to catastrophic memory pressure
### Error Messages/Logs
```shell
```
### Steps to Reproduce
Live inspection of the affected machine: process table and Activity Monitor
process inspector for the host side; a shell inside the guest for kernel, RAM
and virtualization type; direct reads of `~/Library/Logs/Claude/{main,
cowork_vm_swift}.log` and `~/Library/Logs/RustDesk/`. No files were modified and
no processes terminated during the investigation. All times Europe/London.
### Claude Model
Sonnet (default)
### Is this a regression?
Yes, this worked in a previous version
### Last Working Version
_No response_
### Claude Code Version
Claude 1.46388.4 (50e62f) 2026-09-05T01:57:47.000Z
### Platform
Anthropic API
### Operating System
macOS
### Terminal/Shell
Terminal.app (macOS)
### Additional Information
_No response_
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
調査の方向性
Start by reproducing on macOS with Claude Desktop 1.46388.4 and watching Activity Monitor for “Virtual Machine Service for Claude” after Cowork sessions are abandoned. Read the attached logs and trace the Cowork VM lifecycle around session end versus application quit. Done means the VM no longer remains resident across sessions and the memory-pressure scenario no longer leaves an orphaned 4 GB VM.
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- electron, macos, node.js
- 領域
- desktop, performance
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 活発
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 42/100