Sandbox write allowlist missing ~/.claude.json — causes 44GB debug log spam per session

Resolved 💬 3 comments Opened Feb 22, 2026 by Caylub Closed Feb 26, 2026

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

  1. Run Claude Code with sandbox.enabled: true on Linux (bwrap sandbox active)
  2. Start any conversation and use it normally
  3. 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-*.sock and /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:

  1. Add ~/.claude.json to the bwrap writable bind-mounts (--bind ~/.claude.json ~/.claude.json) — simplest fix
  2. Route ~/.claude.json writes through the parent process (outside bwrap) via IPC — architecturally cleaner
  3. Rate-limit or deduplicate EACCES logging — defensive measure regardless of root cause. Logging the same error 155M times is never useful.
  4. Detect write failure and stop retrying — if the first write to ~/.claude.json fails 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.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗