Bash tool denies any command containing $VAR or $(...) with misleading git-push hook message

Status Open
Reported on v2.1.246
Maintainer reply None cached
Activity 0 comments · opened Aug 26, 2026

Claude Code version: 2.1.246 (also reproduced on 2.1.232)
OS: Windows 11, Git Bash shell

Summary

Any Bash-tool command containing a shell variable expansion ($VAR) or command substitution ($(...)) is denied by the permission system, with a misleading error message that appears to come from an unrelated custom hook (git push *-f* / git push *--force* if-gated deny rules) in the project's .claude/settings.local.json.

Reproduction

In a project with these PreToolUse hooks configured (matcher Bash, gated by if):

{
  "type": "command",
  "command": "echo ...Force push is blocked by hook...",
  "if": "Bash(git push *--force*)"
},
{
  "type": "command",
  "command": "echo ...Force push (-f) is blocked by hook...",
  "if": "Bash(git push *-f*)"
}

Run any of the following via the Bash tool (none contain git push):

echo "$PATH"
echo "$PWD"
echo "$USER"
echo $SOME_UNSET_VAR
echo $(date +%Y)

All are denied with tool_result text Force push (-f) is blocked by hook or Force push is blocked by hook, and toolDenialKind: "permission-rule" in the transcript.

echo "$HOME" and plain echo test (no $) both succeed normally, which is the key clue: presence of $ for expansion (with $HOME specifically exempted) appears to trigger the denial, not the if pattern's actual glob logic.

Expected

The if: "Bash(git push *-f*)" condition should only match commands that actually look like git push ... -f .... It should not fire on unrelated commands, and if a different mechanism causes the denial, it should not display this hook's hardcoded message.

Actual

Any command with $VAR/$(...) shell expansion is denied, citing this hook's message even though the hook logic clearly should not match.

Impact

This effectively breaks normal shell scripting (variable assignment, command substitution, reading env vars) through the Bash tool in any project that has an if-gated PreToolUse hook on the Bash matcher, with a misleading error that sends users hunting through the wrong hook

View original on GitHub ↗