Sandboxed Bash fails with "bwrap: Can't create file at .git: Is a directory" in normal (non-worktree) git repos
Description
When Bash sandboxing is enabled (/sandbox), every sandboxed Bash tool call fails in a
plain git checkout (not a worktree) with:
bwrap: Can't create file at <repo>/.git: Is a directory
This appears to happen because the sandbox's bind-mount setup assumes .git is a file
(as it is in a git worktree, where .git is a pointer file), but in a normal clone.git is a directory. This blocks every sandboxed command, including harmless
read-only ones like date.
Environment
- OS: Ubuntu, kernel 6.17.0-29-generic
- Repo: normal git clone (not a worktree)
- Claude Code sandbox mode: enabled via
/sandbox
Steps to reproduce
- In a plain (non-worktree) git repository, run
/sandboxand enable sandboxing. - Run any Bash tool call, e.g.
date.
Expected
Command executes normally inside the sandbox.
Actual
bwrap: Can't create file at /path/to/repo/.git: Is a directory
Every subsequent Bash call fails identically regardless of the command being run —
the sandbox mount setup fails before the wrapped command executes, so the sandbox is
unusable for any non-worktree repo.
Additional context
Before reaching this, we also hit bwrap: loopback: Failed RTM_NEWADDR: Operation not, caused by Ubuntu 24.04+'s
permittedkernel.apparmor_restrict_unprivileged_userns=1
blocking bwrap's unprivileged netns setup. Toggling that sysctl off resolved the netns
error and surfaced the .git bind-mount error above as a separate, reproducible bug.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
I tried to reproduce this on 2.1.233 on Linux (Ubuntu, bubblewrap 0.9.0): fresh
git initrepo with a commit,"sandbox": {"enabled": true}in.claude/settings.json, then sandboxed Bash commands (date,git status,git add, file writes). Everything worked, and the sandbox was verifiably active (writes outside the repo were blocked). Agit worktree addcheckout behaved the same. I also repeated the exact scenario on 2.1.197 (the version you reported) and could not trigger thebwrap: Can't create file at <repo>/.giterror there either.That error indicates the sandbox tried to mount a file over your
.gitdirectory, which shouldn't happen for a plain clone with default settings — so something specific to your setup is likely involved. Could you share:sandboxsection of your~/.claude/settings.jsonand the repo's.claude/settings.json/.claude/settings.local.json— especially anyfilesystem.denyWrite/denyReadentries covering the repo or.git.gitexisted before you launched Claude Code (or was created/re-cloned mid-session)ls -la .gitandgit rev-parse --git-dirin the repoclaude --debug-file /tmp/cc-debug.txt, trigger the failure, and attach the relevant lines🤖 Generated with Claude Code
We weren't able to reproduce this. Could you provide steps to trigger the issue — what you ran, what happened, and what you expected? This issue will be closed automatically if there's no activity within 7 days.
No longer reproducible on my setup — this looks fixed and can probably be closed.
Tested in a plain (non-worktree) clone where
.gitis a directory, which is thecondition described in the report:
.gitis a real directory (drwxrwxr-x 8)"Read-only file system", while
.git/remains writabledateand other commands run normally; nobwrap: Can't create file at <repo>/.git: Is a directoryEnvironment:
kernel.apparmor_restrict_unprivileged_userns=0, so the secondarybwrap: loopback: Failed RTM_NEWADDRsymptom does not apply here eitherCaveat: this is a different kernel and a newer claude-code than the original
report (Ubuntu, kernel 6.17.0-29-generic), so I can't rule out that the bug
still exists on the reporter's configuration. Worth a confirmation from someone
on 24.04+ with the apparmor sysctl set to 1 before closing.