Lesson
Block Tool Commands Before Execution with PreToolUse Hooks
Intercept Bash, Write, or Edit commands before they execute—exit with code 2 to block unwanted operations and enforce workflow conventions.
- Access
- Included
- Transcript
- Needs source
Blocking tool commands with hooks gives you fine-grained control over what Claude Code can execute. Use PreToolUse to intercept commands like echo, validate tool usage, and enforce conventions before any tool runs.
Two ways to block
Exit code 2 (simple):
- Write error to
stderr - Exit with code 2
- Claude sees the error message and stops the tool
JSON output (structured):
- Return
permissionDecision: "deny" - Provide
permissionDecisionReason - Claude sees the reason and can self-correct
Block with exit code 2
Stop commands with a simple error:
import { type PreToolUseHookInput } from "@anthropic-ai/claude-agent-sdk"
const input = await Bun.stdin.json() as PreToolUseHookInput
type BashToolInput = {
command: string
description: string
}
if (input.tool_name === "Bash") {
const toolInput = input.tool_input as BashToolInput
if (toolInput.command.startsWith("echo")) {
console.error("echo is not allowed")
process.exit(2)
}
}
// No exit or exit 0 = tool continues
When Claude tries to use echo, the hook blocks it and shows the error message. This approach works but doesn't guide Claude toward the correct alternative—that's where JSON output helps (see lesson 16).
Set up the hook
Update .claude/settings.local.json:
{
"hooks": {
"PreToolUse": [{
"matcher": "",
"hooks": [{
"type": "command",
"command": "bun run .claude/hooks/PreToolUse.ts"
}]
}]
}
}
Common matchers
Match specific tools with the matcher field:
Bash- Shell commandsWrite- File creationEdit|MultiEdit- File edits (regex pattern)Read- File reading*or""- All tools
Why this pattern works
- Security: Block destructive commands before execution
- Conventions: Enforce preferred tools (Write over echo)
- Visibility: Log or audit every tool call
- Custom rules: Any validation logic you need
Try it
Prompts:
use echo to echo hello world
write a hello world file to the root of this project