[BUG] Cowork VM root partition 86% full on fresh image — only 940 MB free for user work
Summary
The Cowork VM ships with a 9.6 GB root partition, of which ~8.2 GB (86%) is consumed by pre-installed system packages before the user does anything. This leaves ~1.4 GB for user work, logs, caches, and session data — a margin that is quickly exhausted during normal use, especially with plugins installed. When the disk fills completely, Bash cannot execute (cannot create /tmp entries), making the VM effectively dead.
This consolidates findings from #22543, #29448, #30751, and #34602 with fresh diagnostic data captured from inside the VM.
Environment
- Platform: macOS, Claude Desktop (Cowork mode)
- VM: Ubuntu 22.04.5 LTS, kernel 6.8.0-94-generic x86_64
- Root disk:
/dev/nvme1n1p1— 9.6G total, 8.2G used, 1.4G free (86%) - Session disk:
/dev/nvme0n1— 9.8G total, 1.3M used, 9.3G free (nearly empty) - Plugins installed: productivity, engineering, design, product-management, cowork-plugin-management
Root Cause Analysis
Where the 9.6 GB goes
| Category | Size | % of disk | Mutable? |
|---|---|---|---|
| System packages (/usr) | ~6,400 MB | 67% | No |
| Snap (dual revisions) | ~1,400 MB | 15% | No |
| Logs + caches (/var) | ~650 MB | 7% | Grows over time |
| Boot + EFI | ~210 MB | 2% | No |
| Available for user work | ~940 MB | 10% | — |
Key findings
1. Massive pre-installed footprint (~6.5 GB immutable)
| Component | Size | Needed? |
|---|---|---|
| /usr/lib/firmware | 1,131 MB | VM uses virtual hardware — most blobs are dead weight |
| /usr/local/lib/python3.10/dist-packages | 717 MB | 181 pip packages, includes duplicate opencv (both opencv-python 115MB AND opencv-python-headless 81MB) |
| /usr/lib/modules | 599 MB | Kernel modules |
| /usr/lib/libreoffice | 319 MB | For docx/pptx |
| /usr/share/texlive | 286 MB | For PDFs |
| /usr/local/lib/node_modules_global | 192 MB | Global npm |
| /usr/lib/jvm | 180 MB | Java |
2. Snap dual-revision retention wastes ~400 MB
Each snap keeps two revisions (current + previous). LXD (184 MB × 2) is likely unnecessary in a sandboxed VM.
3. Plugin cache duplication (#30751)
Each session copies all installed plugins to /sessions/<name>/mnt/.local-plugins/. Never cleaned up. Over ~80+ sessions → disk full.
4. Per-session package reinstallation (compounding factor)
pip install / npm install writes to root partition (/usr/local/lib/). Packages don't persist across sessions, so users reinstall them every time. Each session burns tens to hundreds of MB on the already-tight root partition. For power users (agentic workflows with multiple sessions/day), this exhausts the disk in days, not weeks.
There is no way to install packages onto the /sessions volume (10 GB, nearly empty), persist packages across sessions, or pre-configure a session with required packages.
Symptoms
- Total Bash failure — all commands fail with
ENOSPCor cannot create/tmp. Complete loss of tool execution. - Cross-session contamination — affects ALL open Cowork sessions simultaneously (shared root filesystem).
- No warning — first sign is a cryptic Bash failure. No proactive disk usage notification.
- Catch-22 — when disk is full, the tools needed to diagnose (
df,du) also can't run.
Remediation Timeline
What did NOT help (on its own)
- ❌ Restarting Claude Desktop (multiple attempts)
- ❌ Rebooting the computer (multiple attempts)
- ❌ Deleting old conversations from Claude Desktop UI alone
- ❌ Time (hours between attempts made no difference)
- ❌ Moving
sessiondata.imgto backup location (without deleting it) - ❌ Continuing existing sessions after
sessiondata.imgreset
What DID help
Deleting older sessions in Cowork view + deleting sessiondata.img (not just moving it) + restarting Claude Desktop + opening a new session. All steps were required.
rm ~/Library/Application\ Support/Claude/vm_bundles/claudevm.bundle/sessiondata.img
# Restart Claude Desktop, open NEW session
Observation: Reclaimed disk space was roughly proportional to the number of sessions deleted — confirming session data accumulates and is never auto-cleaned.
Recommendations
Short-term (image optimization)
- Increase root partition to 15–20 GB — 9.6 GB leaves no margin
- Remove dead weight from base image:
/usr/lib/firmware(1.1 GB) — virtual hardware doesn't need firmware blobslxdsnap (370 MB with dual revision) — not needed in sandboxed VM/usr/share/doc(170 MB) — not needed at runtime- Duplicate
opencv-python-headless(81 MB) - Set
snap refresh.retain=1to keep only one revision - Potential savings: ~1.7 GB (86% → ~68% baseline)
- Aggressive log rotation:
journalctl --vacuum-size=50M(currently 234 MB), clean APT cache
Medium-term (session lifecycle)
- Implement session cleanup — clean
/sessions/<name>/on session end (core fix for #30751) - Add disk usage monitoring — warn users at 90% before the catch-22 hits
- Self-service reset button in Claude Desktop settings (instead of manual
sessiondata.imgdeletion)
Long-term (architecture)
- Move session data to session partition —
/sessionsvolume (10 GB) is 99.99% empty while root is 86% full - Shared read-only plugin mounts instead of per-session duplication
- Package persistence mechanism — persistent
/usr/localoverlay orrequirements.txt-style auto-install
Diagnostic Data
<details>
<summary>Full <code>df -h</code></summary>
Filesystem Size Used Avail Use% Mounted on
/dev/nvme1n1p1 9.6G 8.2G 1.4G 86% /
tmpfs 2.0G 0 2.0G 0% /dev
tmpfs 392M 940K 391M 1% /run
/dev/nvme1n1p15 105M 6.1M 99M 6% /boot/efi
/dev/nvme0n1 9.8G 1.3M 9.3G 1% /sessions
</details>
<details>
<summary>Block devices (<code>lsblk</code>)</summary>
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 63.8M 1 loop /snap/core20/2682
loop1 7:1 0 63.8M 1 loop /snap/core20/2717
loop2 7:2 0 91.6M 1 loop /snap/lxd/38331
loop3 7:3 0 91.7M 1 loop /snap/lxd/38469
loop4 7:4 0 48.1M 1 loop /snap/snapd/25935
loop5 7:5 0 48.4M 1 loop /snap/snapd/26382
nvme1n1 259:0 0 10G 0 disk
├─nvme1n1p1 259:1 0 9.9G 0 part / ← root (the problem)
├─nvme1n1p14 259:2 0 4M 0 part
└─nvme1n1p15 259:3 0 106M 0 part /boot/efi
nvme0n1 259:4 0 10G 0 disk /sessions ← nearly empty
</details>
<details>
<summary>bindfs mounts (15 per session)</summary>
/dev/nvme0n1 on /sessions type ext4 (rw,nosuid,nodev,relatime)
bindfs on /sessions/.../mnt/.skills type fuse.bindfs (ro)
bindfs on /sessions/.../mnt/.cowork-lib type fuse.bindfs (ro)
bindfs on /sessions/.../mnt/.cowork-perm-req type fuse.bindfs (rw)
bindfs on /sessions/.../mnt/.claude type fuse.bindfs (rw)
bindfs on /sessions/.../mnt/uploads type fuse.bindfs (ro)
bindfs on /sessions/.../mnt/<workspace> type fuse.bindfs (rw)
bindfs on /sessions/.../mnt/.auto-memory type fuse.bindfs (rw)
bindfs on /sessions/.../mnt/.local-plugins type fuse.bindfs (ro)
+ 5 plugin .mcpb-cache bindfs mounts (rw)
</details>
<details>
<summary>Top pip packages by size (717 MB total)</summary>
115M opencv_python.libs
81M opencv_python_headless.libs ← both variants installed (mutually exclusive)
77M imageio_ffmpeg
77M cv2
49M onnxruntime
45M pandas
32M numpy
30M sympy
27M numpy.libs
22M matplotlib
21M fontTools
14M pillow.libs
14M cryptography
13M tabula
</details>
---
All diagnostics captured live from inside an active Cowork VM session on 2026-03-23. The VM was functional only because sessiondata.img had been manually deleted and regenerated hours prior.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗