Bash tool denies any command containing $VAR or $(...) with misleading git-push hook message
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