Sandboxed Bash leaves per-invocation writable-overlay tmp directories behind; never cleaned up, fills disk at several GB/hour

Status Open
Reported on v2.1.241
Maintainer reply None cached
Activity 0 comments · opened Sep 2, 2026

What's Wrong?

Every sandboxed Bash invocation that the sandbox redirects (rather than outright denies) — because the command tried to write to a path marked read-only, e.g. bytecode-cache writes into a virtualenv or system Python prefix — creates a writable overlay directory under the job's tmp root (tmp.XXXXXXXXXX-style directory names). This overlay is never removed when the command exits. Every subsequent redirected write creates one more overlay directory, so the tree grows without bound for the life of the session/job.

Observed independently in two unrelated sessions on two different hosts, both running macOS (darwin arm64):

  • Session 1: 265 overlay directories / 6.13 GB in one job's tmp dir, growing at roughly +6 GB/hour while repeatedly running pytest against a project whose venv/interpreter live under paths the sandbox denies write access to.
  • Session 2 (a background job): 682 overlay directories / 6.57 GB in one job's tmp dir, with 85 created in the last 60 minutes and 15 in the last 10 minutes at measurement time (i.e. still actively growing, roughly 1 new directory per sandboxed invocation).

In both cases the overlay contents are exactly a shadow filesystem tree mirroring the paths that were redirected, e.g.:

tmp.<rand>/Users/<user>/<project>/.venv/lib/.../__pycache__
tmp.<rand>/opt/homebrew/Cellar/python@3.14/3.14.6/Frameworks/...

Each overlay is roughly 30-80 MB. None had any open file descriptors at measurement time (checked via lsof) — they are pure leaks, not in-use state.

A comparison session on the same host that did not go through a sandboxed path had zero such directories, isolating the cause to the sandbox's write-redirect overlay mechanism specifically (not general tmp usage by the harness).

Real-world impact: on one host, a differential per-directory disk measurement attributed effectively the entire observed free-space drain (~-5 GiB/hour) to this one directory tree. The same host's disk had separately hit a critically low level earlier the same day, contributing to an unrelated service outage for several hours due to lack of free disk space.

What Should Happen?

The sandbox's writable overlay for a given sandboxed command should be removed when that command's process exits, or at minimum reaped periodically — the same lifecycle any other per-invocation temp directory would get.

Steps to Reproduce

  1. In a Claude Code session, use the sandboxed Bash tool (sandboxing enabled).
  2. Run a Python/pytest command against a project whose interpreter or virtualenv lives at a path the sandbox does not grant write access to, such that bytecode-cache writes (__pycache__) get redirected by the sandbox rather than denied outright.
  3. Repeat the command (or run a test suite that repeatedly imports modules) several times.
  4. Count the overlay directories in the job's tmp root, e.g.: find <job-tmp-root> -maxdepth 1 -name 'tmp.*' -type d | wc -l
  5. Observe the count grows by roughly one directory per sandboxed invocation and never shrinks, even though the invoking commands have long since exited and hold no open file descriptors into those directories.

Error Messages/Logs

Not applicable — no error is surfaced; this is a silent resource leak, only visible via disk-usage measurement.

Claude Code Version

2.1.241 (observed identically on both hosts)

Is this a regression?

I don't know

Platform

Anthropic API (both sessions)

Operating System

macOS (darwin arm64) — two independent hosts, same result on both

View original on GitHub ↗