A PreToolUse hook lets you define file patterns Claude is blocked from writing to. Without it, a misunderstood instruction can overwrite your .env and silently break your environment before you notice.
When the hook script exits with code 2, Claude Code cancels the tool call and sends your message back to Claude, which then adjusts its approach.
Here's a shell script that guards .env and migration files:
#!/bin/bash
PATH_ARG="$CLAUDE_TOOL_INPUT_PATH"
if [[ "$PATH_ARG" == *".env"* ]] || [[ "$PATH_ARG" == *"migrations/"* ]]; then
echo "Blocked: $PATH_ARG is a protected file. Do not write to it."
exit 2
fi
exit 0
I add patterns to match whatever my project considers off-limits. You define the rules once; the hook enforces them on every file write Claude attempts.