claude-code - 💡(How to fix) Fix PreToolUse hook: `if` filter on handler silently matches nothing [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#49703Fetched 2026-04-17 08:33:47
View on GitHub
Comments
2
Participants
2
Timeline
7
Reactions
0
Timeline (top)
labeled ×4commented ×2closed ×1

Two issues with PreToolUse hook handlers configured in settings.json:

Root Cause

Two issues with PreToolUse hook handlers configured in settings.json:

Fix Action

Fix / Workaround

Workaround: Remove if, parse stdin JSON in the command script instead:

Code Example

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(*git commit*)",
            "command": "echo 'FIRED' >> /tmp/hook_test.log"
          }
        ]
      }
    ]
  }
}

---

jq -r '.tool_input.command' | grep -q 'git commit'

---

{
  "type": "agent",
  "prompt": "Run `git diff --cached` and review for issues.",
  "timeout": 120,
  "statusMessage": "Reviewing staged changes..."
}
RAW_BUFFERClick to expand / collapse

Description

Two issues with PreToolUse hook handlers configured in settings.json:

1. if field on hook handler never matches

A command hook with "if": "Bash(*git commit*)" (or "Bash(git commit*)") at the handler level never fires, even though the same hook without if fires correctly on every Bash call.

Steps to reproduce:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(*git commit*)",
            "command": "echo 'FIRED' >> /tmp/hook_test.log"
          }
        ]
      }
    ]
  }
}
  1. Restart Claude Code
  2. Run a Bash tool call containing git commit
  3. Check /tmp/hook_test.log — file does not exist

Expected: Hook fires when the Bash command contains git commit.

Workaround: Remove if, parse stdin JSON in the command script instead:

jq -r '.tool_input.command' | grep -q 'git commit'

This confirms the tool input is available via stdin and the matcher fires — only the if filter is broken.

2. agent type hook produces no visible output

Replacing "type": "command" with "type": "agent" (and adding prompt, timeout, statusMessage), the hook produces no visible effect: no spinner, no status message, no agent output, no file changes from the agent's review.

{
  "type": "agent",
  "prompt": "Run `git diff --cached` and review for issues.",
  "timeout": 120,
  "statusMessage": "Reviewing staged changes..."
}

This may be related to issue 1 (if the if filter was silently suppressing execution), but we also tested without if on a "matcher": "Bash" group and still saw no statusMessage or agent activity.

Expected: The statusMessage should appear while the agent runs, and the agent's changes (if any) should be visible.

Environment

  • Claude Code CLI (latest as of 2026-04-17)
  • Debian 13 (Trixie), Linux 6.19.6, KDE Wayland
  • Model: claude-opus-4-6
  • Settings location: ~/.claude/settings.json (user-level)

extent analysis

TL;DR

The if field issue in PreToolUse hook handlers can be worked around by removing the if filter and parsing stdin JSON in the command script, while the agent type hook issue may require further investigation into the hook's configuration and execution.

Guidance

  • Verify that the if filter is correctly formatted and that the condition is met by checking the stdin JSON output.
  • Test the agent type hook without the if filter to determine if the issue is related to the filter or the hook itself.
  • Check the Claude Code CLI documentation for any specific requirements or limitations for agent type hooks.
  • Consider adding logging or debugging statements to the hook script to gain more insight into its execution.

Example

jq -r '.tool_input.command' | grep -q 'git commit'

This command can be used to parse the stdin JSON and check if the git commit command is present, as a workaround for the if filter issue.

Notes

The issues may be related, but further investigation is needed to determine the root cause. The agent type hook issue may require additional configuration or setup to function correctly.

Recommendation

Apply workaround: Remove the if filter and parse stdin JSON in the command script, as this has been confirmed to work in the provided example. For the agent type hook issue, further investigation and potentially additional configuration are needed to resolve the issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix PreToolUse hook: `if` filter on handler silently matches nothing [2 comments, 2 participants]