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 commands
  • Write - File creation
  • Edit|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