[BUG] 2.1.281: CLAUDE_CODE_SUBPROCESS_ENV_SCRUB sandbox denies $HOME/actions-runner, so every Bash call fails on a default self-hosted GitHub Actions runner
What's wrong
On a self-hosted GitHub Actions runner installed with GitHub's default layout (runner in ~/actions-runner, work folder ~/actions-runner/_work), every Bash tool call fails before the command runs when CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1:
bwrap: Can't create file at /root/actions-runner/_work/<repo>/<repo>/.git/config.lock: Read-only file system
anthropics/claude-code-action turns the scrub on whenever allowed_non_write_users is set, so review workflows on such runners lose all shell access (including git diff) and continue without it.
Cause (from the captured bwrap argv)
The scrub denyWrite list includes ${HOME}/actions-runner (and ${HOME}/runners). In the default self-hosted layout, GITHUB_WORKSPACE is inside that directory, so the sandbox emits --ro-bind /root/actions-runner /root/actions-runner after the workspace --bind. The whole workspace becomes read-only. The next deny entry for the non-existent <workspace>/.git/config.lock needs a /dev/null stub file, which bubblewrap cannot create on the read-only mount, so bwrap exits.
Relevant argv excerpt:
--bind /root/actions-runner/_work/<repo>/<repo> /root/actions-runner/_work/<repo>/<repo>
...
--ro-bind /root/actions-runner /root/actions-runner
--ro-bind /dev/null /root/actions-runner/_work/<repo>/<repo>/.git/config.lock
Reproduction
- Claude Code 2.1.281 (native), Ubuntu 24.04, kernel 6.8, bubblewrap 0.9.0, running as root,
kernel.apparmor_restrict_unprivileged_userns=0. - Runner installed per GitHub's instructions at
/root/actions-runner, default_workfolder. - From the workspace, with
HOME=/root,GITHUB_WORKSPACE=<workspace>,CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1, runclaude -pand have the model call Bash withgit rev-parse HEAD. I drove it with a local mock Messages API, so no model call is needed to reproduce.
Expected
When the workspace (or cwd) is inside a runner install path, the sandbox should write-protect the runner's own files (bin, externals, .runner, .credentials, _diag, and so on) and leave the workspace writable, or it should fail with a clear message at startup. Today every Bash call fails, and the run continues silently.
Related
- #79997 (ancestor denyWrite stubs, fixed in 2.1.227). A second failure on the same runner host, which may be a regression of that fix, is filed separately.
---
Created with LLM: Opus 5.5 | medium | Harness: Claude Code
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗