claude-code - 💡(How to fix) Fix PreToolUse hook `if` pattern does not match commands chained with `&&` or `;` [1 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#46056Fetched 2026-04-11 06:30:08
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
labeled ×2subscribed ×1

PreToolUse hook's if pattern matching (e.g., Bash(git commit*)) only matches the beginning of the full Bash command string. When the model chains commands with && or ;, the pattern fails to match and the hook is silently skipped.

Error Message

  • Warn when a Bash call contains a command that would match a hook pattern but is skipped due to chaining

Root Cause

Users set up PreToolUse hooks to enforce quality gates (linting, tests, branch protection) before specific commands. The model frequently chains commands with && for efficiency, which inadvertently bypasses all hook-based guardrails. This is especially problematic because:

Code Example

{
  "type": "command",
  "if": "Bash(git commit*)",
  "command": "bash .claude/hooks/guard-commit-lint.sh",
  "statusMessage": "Running pre-commit checks..."
}
RAW_BUFFERClick to expand / collapse

Summary

PreToolUse hook's if pattern matching (e.g., Bash(git commit*)) only matches the beginning of the full Bash command string. When the model chains commands with && or ;, the pattern fails to match and the hook is silently skipped.

Reproduction

Hook configuration in .claude/settings.json:

{
  "type": "command",
  "if": "Bash(git commit*)",
  "command": "bash .claude/hooks/guard-commit-lint.sh",
  "statusMessage": "Running pre-commit checks..."
}
  • git commit -m "msg" — hook fires correctly
  • git checkout -b branch && git add . && git commit -m "msg" — hook does not fire

The if pattern matches against the full command string, which starts with git checkout, not git commit.

Impact

Users set up PreToolUse hooks to enforce quality gates (linting, tests, branch protection) before specific commands. The model frequently chains commands with && for efficiency, which inadvertently bypasses all hook-based guardrails. This is especially problematic because:

  1. There is no warning or log when a hook is skipped due to pattern mismatch
  2. The user has no way to express "match if git commit appears anywhere in the command" with the current if syntax

Possible solutions

  • Match the if pattern against each individual command in a &&/;/|| chain, not just the full string
  • Support substring or regex matching in if patterns (e.g., Bash(*git commit*))
  • Warn when a Bash call contains a command that would match a hook pattern but is skipped due to chaining

extent analysis

TL;DR

Modify the if pattern in the PreToolUse hook configuration to support substring or regex matching to correctly identify commands within a chained sequence.

Guidance

  • Consider updating the if pattern to use a substring match, such as Bash(*git commit*), to ensure the hook fires when git commit appears anywhere in the command string.
  • Alternatively, modify the hook configuration to match each individual command in a &&/;/|| chain, rather than just the full string.
  • To mitigate the issue, users can temporarily avoid chaining commands with && and instead run each command separately to ensure hooks are triggered as expected.
  • Investigate adding a warning or log message when a hook is skipped due to pattern mismatch to improve visibility into hook behavior.

Example

{
  "type": "command",
  "if": "Bash(*git commit*)",
  "command": "bash .claude/hooks/guard-commit-lint.sh",
  "statusMessage": "Running pre-commit checks..."
}

Notes

The proposed solution relies on modifying the if pattern to support substring matching, which may require updates to the underlying hook configuration parser. Additionally, the issue may be resolved by modifying the hook to match individual commands in a chain, but this approach may require significant changes to the hook implementation.

Recommendation

Apply workaround by modifying the if pattern to use substring matching, as this approach is likely to be easier to implement and test than modifying the hook to match individual commands in a chain.

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