[BUG] examples/hooks/bash_command_validator_example.py: regex bugs cause silent false negatives on common shapes

Status Closed — not planned
Maintainer reply None cached
Activity 2 comments · opened May 15, 2026 · closed Jun 14, 2026

What's Wrong?

The bash validator hook example silently fails to flag two common command shapes that the rules were intended to catch:

  1. grep as the source of a pipeline (e.g. grep foo | wc -l) is exempted by the negative lookahead (?!.*\|), even though grep is the leading command and rg foo is the better substitute. The lookahead was apparently intended to exempt grep-as-downstream-filter (e.g. cat foo | grep bar), but the ^grep\b anchor already handles that case correctly — the lookahead does no useful work and produces a false negative.
  1. find invocations with predicates before -name (e.g. find / -type f -name '*.log') are missed because the regex ^find\s+\S+\s+-name\b only accepts find PATH -name. This shape is arguably the most common real-world form of find -name.

What Should Happen?

Both shapes should match their respective rules. Empirical case matrix (run against examples/hooks/bash_command_validator_example.py at HEAD):

| Command | Current | Should be |
|---|---|---|
| grep foo \| wc -l | not flagged | flagged |
| grep foo bar.txt \| head -5 | not flagged | flagged |
| find / -type f -name '*.log' | not flagged | flagged |
| find . -type d -name node_modules | not flagged | flagged |
| find . -maxdepth 2 -name '*.md' | not flagged | flagged |

Steps to Reproduce

  1. Open examples/hooks/bash_command_validator_example.py at HEAD of anthropics/claude-code.
  2. Copy _VALIDATION_RULES into a Python REPL.
  3. Run:

``python
import re
re.search(r"^grep\b(?!.*\|)", "grep foo | wc -l") # returns None — bug
re.search(r"^find\s+\S+\s+-name\b", "find / -type f -name '*.log'") # returns None — bug
``

Claude Code Version

N/A — bug is in examples/hooks/bash_command_validator_example.py at HEAD of anthropics/claude-code, observable by reading the file.

Platform / OS / Terminal

N/A — file-level bug in a checked-in example.

Is this a regression?

No, this never worked.

Additional Information

Fix is two regex tweaks (drop the broken lookahead, allow predicates between find and -name). Happy to send a PR if you'd like — let me know if there's a preferred scope (e.g. fix-only vs. fix-plus-test-file). Considered switching to shlex-based parsing to also catch prefix forms (sudo grep, time grep, etc.) but that would substantially expand the example's scope; can do as a follow-up if desired.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗