[Bug] Worktree isolation guard false positive: substring match on "git" blocks commands
Bug Description
Worktree-isolation guard has false positives from naive substring matching on "git". In a worktree-isolated session, any Bash command containing the substring "git" anywhere (even inside a word) is refused if it also contains a shell expansion. Repro: mvn -Dmaven.gitcommitid.skip runs, but mvn -Dmaven.gitcommitid.skip; echo exit=$? is refused with "names git in a form too complex to verify that it stays inside the worktree". Likewise grep -n 'git-commit-id' ~/.m2/repository/io/airlift/airbase/*/airbase-*.pom is refused: the quoted grep pattern is treated as a git invocation and the glob as git's argument. Neither command runs git. Real-world impact: a plain Maven build (mvn ... -Dmaven.gitcommitid.skip > log 2>&1; echo exit=$?) was blocked, and the subagent worked around it with a wrapper script, which defeats the purpose of the guard. Please parse the command and match git only in command position (the program actually being executed), not as a substring of arguments, flags or patterns.
Environment Info
- Platform: darwin
- Terminal: ghostty
- Version: 2.1.295
- Feedback ID: 3b707d92-8455-4893-aeea-c72f32c318ae
3 Comments
Same on 2.1.296. A common trigger is repos under ~/git/: every absolute path contains "git", so any loop, $VAR, $PWD, or
; echo exit=$?alongside a path gets refused. Examples that never run git:for s in a b c; do DAGSTER_HOME=~/git/repo/.claude/worktrees/wt mytool find --substring $s; done
cd ~/git/repo/.claude/worktrees/wt && DAGSTER_HOME=$PWD mytool test > /tmp/x.log 2>&1; echo exit=$?
Same bug on 2.1.295 (macOS), hit at scale. In one orchestrated session, 62
isolation: worktreesubagents had Bash calls refused with "names git in a form too complex to verify that it stays inside the worktree". Of 77 refused commands, 43 ran no git at all. The repo has aplugins/git-tools/directory and agit-branch-syncscript, so "git" appears in the paths.Refused commands that never run git:
The last one is a commit-message file. The word only appears in the heredoc's body.
The refusal comes from the Bash tool itself, after the permission layers have already allowed the call. For one refused call, the transcript record shows:
PreToolUse:Bashhook exited 0 and returned{"hookSpecificOutput":{"hookEventName":"PreToolUse"}}, so it abstained;permissionDecisionis{"decision":"accept","source":"config","reasonType":"classifier"}, so the auto-mode classifier accepted it;toolUseResultis"Error: This agent is isolated in the worktree …, but this command names git in a form too complex to verify …".No hook or permission rule can allow these commands back. Every agent working in a repo whose paths contain "git" pays for it in retries and reworded commands.
Another data point, from a retrospective count over my local Claude Code transcripts (2026-07-26 to 2026-10-12; 544 interactive sessions and 2,639 subagent transcripts; tool calls deduplicated by
tool_use.id):gitorghword at all. It only contained the substringgithub, because the repositories are checked out under a.../github.com/<owner>/<repo>layout, so every absolute path matches.git -C47,cd23, working directory resolving there 26). So I would rather see git matched only in command position, as the original report suggests, than have the guard disabled.