[BUG] 2.1.281: scrub sandbox still fails to create ancestor .claude stub when the ancestor is owned by another uid (as root, --cap-drop ALL)

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

What's wrong

With CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1, every Bash tool call fails before the command runs:

bwrap: Can't mkdir /root/actions-runner-2/.claude: Permission denied

This looks like a variant of #79997 (fixed in 2.1.227) that still occurs on 2.1.281.

Environment

  • Claude Code 2.1.281 (native), Ubuntu 24.04, kernel 6.8, bubblewrap 0.9.0, kernel.apparmor_restrict_unprivileged_userns=0.
  • Claude runs as root. The cwd is /root/actions-runner-2/_work/<repo>/<repo> (a second self-hosted GitHub Actions runner).
  • /root/actions-runner-2 is owned by uid 1001 with mode 755, as extracted from GitHub's runner tarball. All directories below it are owned by root.

Cause (from the captured bwrap argv)

The sandbox adds denyWrite entries for <ancestor>/.claude (and .mcp.json) at every ancestor of the cwd, and for missing paths it adds --ro-bind /tmp/claude-empty-XXXX <ancestor>/.claude. bwrap runs with --unshare-user --cap-drop ALL. Inside that user namespace, uid 1001 is unmapped, so root has no DAC override on /root/actions-runner-2 and cannot create the mount-point stub. The stubs under root-owned ancestors (_work/.claude, _work/<repo>/.claude) are fine.

A minimal bwrap test on the same host shows the same result:

bwrap --unshare-pid --unshare-user --cap-drop ALL --ro-bind / / --bind /tmp /tmp \
  --ro-bind /tmp/empty /tmp/t/u1001/.claude true   # fails: Can't mkdir ... Permission denied
# same command with /tmp/t/u0 (owned by root) succeeds

Expected

A missing ancestor stub that cannot be created should not kill every Bash call. For example, the fix from #79997 could also cover ancestors that the process owner cannot write to inside the user namespace, not only root-owned ancestors seen by a non-root user.

Related

  • #79997
  • #97730 (the same runner host, where $HOME/actions-runner is also denied)

---
Created with LLM: Opus 5.5 | medium | Harness: Claude Code

View original on GitHub ↗