PreToolUse hook `allow` does not suppress prompt for compound commands leading with `cd … 2>/dev/null || cd …` (2.1.207 fix incomplete)

Open 💬 1 comment Opened Jul 13, 2026 by daniel-sullivan

What's wrong

A PreToolUse hook for Bash that returns a well-formed permissionDecision: "allow" (exit 0) does not suppress the native permission prompt for a compound command that leads with cd … 2>/dev/null || cd … and also contains other redirects / command substitution / a loop. The tool still requires manual confirmation despite the hook approving it.

This looks like an incomplete fix for the 2.1.207 change:

2.1.207 — Fixed compound commands with cd prompting for permission when the only output redirect was to /dev/null

The narrow "the only output redirect was to /dev/null" case is fixed, but compound commands that lead with a cd chain and have more than one redirect (and/or $(…) / a while loop) still prompt.

This is distinct from #52822 (general hook-allow suppression regression), which was fixed in 2.1.140 and is working correctly here for simple tools.

Version

2.1.207 (Claude Code), macOS (darwin 25.3.0), interactive mode.

Reproduction

  1. Minimal always-allow PreToolUse Bash hook:
cat > /tmp/allow-hook.sh <<'EOF'
#!/usr/bin/env bash
cat >/dev/null
echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","permissionDecisionReason":"test"}}'
exit 0
EOF
chmod +x /tmp/allow-hook.sh
  1. Wire it in ~/.claude/settings.json:
{ "hooks": { "PreToolUse": [
  { "matcher": "Bash", "hooks": [ { "type": "command", "command": "/tmp/allow-hook.sh" } ] }
] } }
  1. Ask Claude to run a compound command that leads with a cd chain and has additional redirects, e.g.:
cd /path/to/repo-a 2>/dev/null || cd /path/to/repo-b
while true; do
  out=$(gh pr checks 123 --repo owner/private-repo 2>/dev/null)
  [ -z "$out" ] && { sleep 20; continue; }
  if ! echo "$out" | grep -qiE "pending|in_progress|queued"; then
    echo "PR#123 CI settled: $(echo "$out" | grep -ciE '\bfail') failing"
    break
  fi
  sleep 30
done

Expected

Hook returns allow, so the command runs with no native prompt.

Actual

The native "Do you want to run this command?" prompt appears and blocks on manual confirmation. Removing the leading cd … 2>/dev/null || cd … prefix (the command is otherwise self-contained — the gh call is --repo-qualified and needs no cwd) makes the prompt go away, isolating the cd chain as the trigger.

Evidence the hook approves it

The hook emits a valid allow for the exact command (verified independently of Claude Code):

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "permissionDecisionReason": "..."
  }
}

So the decision is being produced correctly and (per the 2.1.140 fix for #52822) should be honored — the compound-cd permission path appears to be evaluated separately from, and not suppressed by, the hook allow.

Related

  • #52822 — general hook-allow suppression regression, fixed in 2.1.140 (working here; this report is a narrower, still-open case).

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗