Sandbox (bubblewrap) fails in git worktrees due to .git file structure

Status Open
Reported on v2.1.3
Maintainer reply None cached
Activity 5 comments · opened Jan 10, 2026

Preflight Checklist

  • [x] I searched existing issues and this bug hasn't been reported
  • [x] This is a single bug report (not multiple bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The bubblewrap sandbox fails when Claude Code runs in a git worktree. All sandboxed bash commands fail with:

bwrap: Can't mkdir parents for /path/to/worktree/.git/hooks: Not a directory

This forces dangerouslyDisableSandbox: true for every bash command in worktrees, degrading security.

What Should Happen?

Sandboxed bash commands should work in git worktrees the same as in regular repositories.

Steps to Reproduce

  1. Enable sandbox (default on Linux with AppArmor userns workaround)
  2. Verify sandboxed bash works in main repo: cd /path/to/repo && claude → run any bash command
  3. Create worktree: git worktree add .worktrees/test -b test HEAD
  4. Run claude in worktree: cd .worktrees/test && claude
  5. Execute any sandboxed bash command (e.g., ls)
  6. Result: Fails with "Can't mkdir parents for .git/hooks: Not a directory"

Root Cause

Git worktrees use a .git file (not directory) containing a pointer:

gitdir: /path/to/main/repo/.git/worktrees/worktree-name

bwrap tries to bind mount .git/hooks but fails because .git is a file. Since bwrap is fail-closed (correct security behavior), the entire sandbox aborts with exit code 1.

Is this a regression?

No, this never worked

Claude Code Version

2.1.3

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux (Ubuntu 24.04)

Terminal/Shell

Other (Gnome Terminal, also reproduced in VS Code integrated terminal)

Additional Information

  • kernel.apparmor_restrict_unprivileged_userns = 1 (Ubuntu 24.04 default)
  • Custom /etc/apparmor.d/bwrap-userns to enable bwrap (standard workaround)
  • Sandbox works correctly in main repo, only fails in worktrees
  • Workaround: Manually approve dangerouslyDisableSandbox: true for all bash commands

Suggested fix: Detect worktree .git file structure and either resolve to actual .git directory via the gitdir: pointer, or skip .git/hooks bind mounting for worktrees.

View original on GitHub ↗

5 Comments

Passeli · 7 months ago

Please fix this as currently it's impossible to set the bash command permissions such that those would actually work without constant permissions dialog interruptions. Workflow like this is such basic stuff that it's really strange that it does not work.

qte77 · 6 months ago

Still hitting this in Claude Code v2.1.52 (Feb 2026). The built-in EnterWorktree tool creates worktrees under .claude/worktrees/ but then all git operations (merge, commit) fail because bwrap's denyWithinAllow blocks writes to .git/worktrees/<name>/HEAD, ORIG_HEAD, etc. The rules match bare path suffixes regardless of directory depth, so there's no way to exclude .git/worktrees/ subdirectories. The EnterWorktree tool and sandbox are incompatible — worktrees can be created but no git write operations work inside them.

🤖 Generated with Claude noreply@anthropic.com

3f6a · 5 months ago

Friendly bump. I'm hitting this now.

3f6a · 5 months ago
taoyouh · 2 months ago

In my latest test, worktree itself isn't an issue anymore. However if .git/hooks is a symbolic link to an external directory, this fails again with a similar error.

It seems that some sensitive places are added to the sandbox deny list by default, but bwrap cannot launch if any of those places is a symbolic link.