A hook that doesn't work is worse than no hook at all. It gives you false confidence that you're protected while dangerous commands slip through. Here's how to validate your hooks actually block what they should.
Most Claude Code hook guides show you a script and say "save it." But hooks are regex-based shell scripts — the most brittle category of software. A single misplaced backslash, a missing quote, or a wrong exit code silently disables your protection.
Common failure modes
exit 1 instead of exit 2 — allows the command instead of blockingrm -rf but not rm -r -f (flag splitting)git push --force but not git push -fSimulate what Claude Code sends to your hook:
# Should exit 2 (blocked)
echo '{"tool_input":{"command":"rm -rf /"}}' | bash your-hook.sh
echo $? # expect: 2
# Should exit 0 (allowed)
echo '{"tool_input":{"command":"rm temp.txt"}}' | bash your-hook.sh
echo $? # expect: 0
# Flag splitting
echo '{"tool_input":{"command":"rm -r -f /"}}' | bash your-hook.sh
# Quoted paths
echo '{"tool_input":{"command":"rm -rf \"/important/path\""}}' | bash your-hook.sh
# Compound commands
echo '{"tool_input":{"command":"cd /tmp && rm -rf *"}}' | bash your-hook.sh
Verify your hook doesn't block legitimate commands:
# Should NOT be blocked
echo '{"tool_input":{"command":"git status"}}' | bash your-hook.sh
echo '{"tool_input":{"command":"npm test"}}' | bash your-hook.sh
echo '{"tool_input":{"command":"cat README.md"}}' | bash your-hook.sh
cc-safe-setup ships with 9,200+ tests covering 655 example hooks. Every hook is tested for:
# Run the full test suite
npx cc-safe-setup --test
# Verify your installed hooks
npx cc-safe-setup --doctor
npx cc-safe-setup
Every hook validated with comprehensive tests. Zero false positives in production. 9,200+ tests 655 examples
GitHub · npm · Getting Started
npx cc-health-check
Free 20-point diagnostic for your Claude Code setup.
Open source, zero dependencies. View source.
Related: rm -rf · force-push · if field · autonomous · all tools
Learn more: Production Guide · All Tools