[BUG] examples/hooks/bash_command_validator_example.py: regex bugs cause silent false negatives on common shapes
What's Wrong?
The bash validator hook example silently fails to flag two common command shapes that the rules were intended to catch:
grepas the source of a pipeline (e.g.grep foo | wc -l) is exempted by the negative lookahead(?!.*\|), even though grep is the leading command andrg foois the better substitute. The lookahead was apparently intended to exempt grep-as-downstream-filter (e.g.cat foo | grep bar), but the^grep\banchor already handles that case correctly — the lookahead does no useful work and produces a false negative.
findinvocations with predicates before-name(e.g.find / -type f -name '*.log') are missed because the regex^find\s+\S+\s+-name\bonly acceptsfind PATH -name. This shape is arguably the most common real-world form offind -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
- Open
examples/hooks/bash_command_validator_example.pyat HEAD ofanthropics/claude-code. - Copy
_VALIDATION_RULESinto a Python REPL. - 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.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗