[Windows] Chroma prewarm loop: 10,014 failed uvx installs in 26 days, each left a uv builds-v0 env behind (~320 GB)
Bug description
On Windows, the worker's Chroma prewarm failed 10,014 times in 26 days (Aug 22 – Sep 17) with zero successful connections, retrying about once a minute while the worker was running:
uvx --python 3.13 --with onnxruntime>=1.20 --with protobuf<7 --from chroma-mcp==0.2.6 chroma-mcp --help
Each failed attempt left a temporary virtual environment behind in %LOCALAPPDATA%\\\uv\cache\builds-v0\.tmpXXXXXX. I found 10,023 of them: roughly 18.5 million files and ~320 GB of real disk space (estimated from a random sample of 150; 95% range 268–373 GB). On Aug 31 the drive filled up completely: two attempts failed with os error 112 (disk full). The rest of the uv cache was under 1 GB.
The symptom matches #2897 and #3540, but the mechanism is different, and neither the graceful-kill fix (#3541) nor process-tree ownership (#3644) covers it:
- No kill is involved. In 10,009 of the 10,014 failures,
uvxexited on its own with code 2; only 5 were the 120 s prewarm timeout. The temp env is left behind anyway. Each day's failure count in the worker log equals that day's count of newbuilds-v0directories (e.g. 246, 522 and 391 on Sep 14, 15 and 16). - It gets permanently worse. The leftover envs keep hard links to files in
archive-v0. After 1,025 leftovers had built up, attempts started failing withos error 1142, NTFS's limit of 1,023 hard links per file. From then on most attempts failed that way, and each left another env behind. - The retry loop has no limit. The same few errors repeated for weeks, and nothing stopped the loop short of turning Chroma off.
What uv reported
Parsed from the full stderr of every failed prewarm in the worker logs:
| Failures | uv error | First seen |
|---|---|---|
| 1,841 | Failed to install: jsonpointer-3.1.1 / jsonpatch-1.33 … failed to remove directory …\<pkg>.data: The process cannot access the file because it is being used by another process. (os error 32) |
Aug 22 |
| 6,591 | failed to hardlink file … An attempt was made to create more links on a file than the file system supports. (os error 1142) |
Aug 25, after 1,025 os error 32 failures |
| 1,574 | The wheel is invalid: Wheel contains an invalid entry (directory) in the scripts directory: …\<pkg>.data\scripts\.tmpXXXXXX: jsonpointer or jsonpatch again, with a new temp name each time. The cached wheels themselves contain no such directory. |
Sep 2 |
| 5 | prewarm timed out after 120000 ms | Sep 17 |
| 3 | an index fetch timeout (Aug 28); two copy failures with os error 112, disk full (Aug 31) |
Isolation
- Installing the same package set offline from the same (by then saturated) cache into a fresh venv, default hardlink mode,
uv pip install --offline "chroma-mcp==0.2.6" "onnxruntime>=1.20" "protobuf<7", fails in 3 s withos error 1142. - The same command with
--link-mode copyinstalls 107 packages in 15 s, andchroma-mcp --helpthen runs normally.
Expected behavior
- A prewarm that keeps failing the same way should stop retrying (circuit breaker or capped backoff) and report Chroma as unavailable, instead of looping indefinitely.
- A failed prewarm should not leave unbounded disk usage behind.
Suggestions
- Circuit-break the prewarm after N consecutive failures and surface that in health/status output.
- On Windows, spawn the sidecar with
UV_LINK_MODE=copy. In my test that avoided every error above. - After a failed prewarm, remove the
builds-v0entries that attempt created. uv on Windows does not reliably clean them up itself.
I couldn't find a link-mode setting, a failure cap, or any builds-v0 cleanup in src/services/sync/ChromaMcpManager.ts on main, so this likely still applies unless #3694 removes the Python sidecar.
Workaround
Set "CLAUDE_MEM_CHROMA_ENABLED": "false" in ~/.claude-mem/settings.json, run bun <plugin>/scripts/worker-service.cjs restart, then delete the contents of %LOCALAPPDATA%\\\uv\cache\builds-v0. Note: uv cache prune does not touch builds-v0.
Environment
- claude-mem 13.15.0 (plugin, thedotmack marketplace), default settings (
CLAUDE_MEM_CHROMA_MODE=local, prewarm timeout 120000 ms) - Windows 10 Home 10.0.19045, NTFS
- uv 0.10.8, uv-managed CPython 3.13.12
- Claude Code 2.1.240, bun 1.4.0, Node v24.15.0
Related: #2897, #3540, #3541, #3602, #3610, #3644, #3694
Source: thedotmack/claude-mem