[BUG] bwrap fails in a worktree when .claude/skills is a symlink in a repository
Status Fixed / completed
Reported on v2.1.92
Maintainer reply None cached
Workaround ✓ Mentioned in thread ↓
Activity 6 comments · opened Apr 7, 2026 · closed Aug 19, 2026
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Hello,
Our repository at my job has the following setup:.ai-agents/skills.claude/skills --> ../.ai-agents/skills
This causes Claude to fail with sandbox: true, bwrap installed and launching with --worktree. See error message below.
What Should Happen?
sandbox: true is expected to work with worktrees regardless of repository structure.
Error Messages/Logs
● Bash(pwd && ls .claude/)
⎿ Error: Exit code 1
bwrap: Can't create file at /home/claude-aiven-3/git/aiven-core/.claude/skills: Is a
directory
Steps to Reproduce
- Create a new git repository
mkdir -p .ai-agents/skillsmkdir .claude- Symlink
.claude/skillsto point to.ai-agents/skills - Launch Claude Code from this workspace with
claude --worktree testwith sandbox enabled in settings.json - Have the Claude instance execute a bash command
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.92 (Claude Code)
Platform
AWS Bedrock
Operating System
Other Linux
Terminal/Shell
Other
Additional Information
The problem goes away with copy-pasted directories. I would guess that bwrap has a problem when copying over the .claude directory because it doesn't check the subdirectories existing with lstat, although I could be wrong.
Showing cached comments. Read the full discussion on GitHub ↗
5 Comments
Same error in 2.1.118 / 2.1.119 / 2.1.121, with the entire .claude/ (not just .claude/skills) being the symlink. Workaround: sandbox.enabled: false.
Here is a bwrap workaround (tested on Ubuntu 22.04 / 24.04) :
Still reproduces on 2.1.159 (Linux x86_64, bubblewrap). Same layout as the repro:
.claude/skillsis a symlink to../.agents/skills(a real directory), used as a single-source-of-truth so skills can be shared across agent tools.With
sandbox.enabled: true, sandbox init aborts for every Bash command (eventrue), before the command runs:The harness auto-adds
.claude/skillsto the sandbox deny list and masks it by binding an empty file over it, withoutlstat-following the symlink. Since it resolves to a directory, bwrap fails with EISDIR. A symlinked file (e.g. asettings.json) masks fine — only symlinked directories break.The only clean local workaround is
sandbox.enabled: false, which also disablesautoAllowBashIfSandboxed. A proper fix wouldlstatthe deny path and bind an empty directory when it resolves to a dir/symlinked-dir. Likely the same root cause as #40133.Issue still present with version
2.1.177as of 14/06/2026Still present in version
2.1.199When a protected path inside the project's .claude/ directory (commands, agents,
rules) is a symlink to a directory, sandbox mount setup fails and every sandboxed Bash
command errors before running:
bwrap: Can't create file at /home/user/repo/.claude/commands: Is a directory