Sandbox write allowlist missing ~/.claude.json — causes 44GB debug log spam per session
Summary
Claude Code's bwrap sandbox mounts the root filesystem read-only (--ro-bind / /) but does not re-mount ~/.claude.json as writable. The main Claude process runs inside bwrap and periodically writes to ~/.claude.json (via recordUserActivity or similar). Every write attempt fails with EACCES and gets logged to ~/.claude/debug/, which IS writable inside the sandbox. This creates a feedback loop producing ~155 million EACCES errors and ~44 GB of debug log output per session.
Environment
- Claude Code: 2.1.50
- OS: Pop!_OS (Ubuntu-based), Linux 6.17.9-76061709-generic
- bubblewrap: 0.6.1
- Sandbox config:
"sandbox": { "enabled": true }(default) - Settings:
defaultMode: "bypassPermissions"
Reproduction
- Run Claude Code with
sandbox.enabled: trueon Linux (bwrap sandbox active) - Start any conversation and use it normally
- Observe the debug log growing rapidly:
# During a session:
ls -lh ~/.claude/debug/<session-id>.txt
# Shows multi-GB file growing in real-time
# Count EACCES errors:
grep -c 'EACCES.*claude\.json' ~/.claude/debug/<session-id>.txt
# Returns tens of millions of hits
Root Cause Analysis
The bwrap sandbox has 6 writable bind-mounts:
/tmp/claude-<uid>/(sandbox temp)<working-directory>(project files)~/.npm/_logs~/.claude/debug/tmp/claude-http-*.sockand/tmp/claude-socks-*.sock(proxy)
Missing from writable paths: ~/.claude.json
The ~/.claude.json file is where Claude Code persists session state and user activity data. The Node.js process running inside bwrap attempts to write this file, but because it falls under the read-only root mount (--ro-bind / /) and is not selectively re-mounted writable, the open() syscall returns EACCES.
Each failed write generates a log line in ~/.claude/debug/<session-id>.txt. Since the activity recorder fires frequently (appears to be on every API round-trip or tool use), a typical session generates 155+ million failures.
Impact
- Disk exhaustion: 44 GB per session, 145 GB total across a few sessions. On a 929 GB drive, this consumed 16% of total disk space.
- I/O overhead: Constant write failures + debug logging creates unnecessary disk I/O
- Silent failure: No user-visible warning that session state isn't being persisted
- Debug logs become unusable: Legitimate debug information is buried under millions of identical EACCES lines
Suggested Fix
One or more of:
- Add
~/.claude.jsonto the bwrap writable bind-mounts (--bind ~/.claude.json ~/.claude.json) — simplest fix - Route
~/.claude.jsonwrites through the parent process (outside bwrap) via IPC — architecturally cleaner - Rate-limit or deduplicate EACCES logging — defensive measure regardless of root cause. Logging the same error 155M times is never useful.
- Detect write failure and stop retrying — if the first write to
~/.claude.jsonfails with EACCES, don't retry on every subsequent activity tick
Workaround
Setting "sandbox": { "enabled": false } in settings.local.json disables bwrap entirely, which stops the EACCES errors. This is viable when running under an external sandbox (e.g., Landlock-based tools), but loses bwrap's network namespace and seccomp protections.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗