Claude Code

Claude Code hooks: how to stop an action before it runs

A Claude Code hook is a handler that runs automatically at a fixed point in a session, such as a command, an HTTP call or a prompt. The PreToolUse hook runs before Claude uses a tool and can stop the call with exit code 2 or a deny decision, and the reason goes back to Claude.

Updated

What are Claude Code hooks?

Handlers you define that run at session events, for example before and after a tool call or when a prompt is submitted. A handler can be a shell command, an HTTP endpoint, a tool on an MCP server, a prompt evaluated by a model, or a subagent. You configure them in settings.json, by event and matcher.

What does the PreToolUse hook do?

  • It runs before the tool call and receives JSON on stdin with tool_name and tool_input.
  • Exit code 2 blocks the call, and the text on stderr goes to Claude as the reason.
  • It can also return JSON with a permissionDecision of allow, deny, ask or defer.
  • A clean exit with no output approves nothing, and the normal permission flow applies.

What does a useful hook look like?

A PreToolUse hook on Bash reads the command and blocks it when it tries to delete a whole folder, with a reason Claude can read. Another hook filters test output so only the failures reach Claude.

Hook or permission rule?

Permission rules are evaluated in the order deny, ask, allow, and the first match wins. A PreToolUse hook does not bypass them: a deny rule blocks even when the hook answered allow. In the other direction, a hook that exits with code 2 stops the call before any rule is checked, even an allow rule.

Where does a hook fall short?

  • The if filter on a handler is best-effort. For a hard allow or deny, the docs point to permission rules.
  • Read and Edit rules don't catch a script that opens files itself, and Bash rules only match the command text. OS-level isolation comes from the sandbox.
  • For high-impact actions, OWASP also recommends human approval.

Frequently asked questions

What does exit code 2 do in a hook?

On events that can block, it stops the action and stderr becomes the reason shown to Claude. The block holds even if the hook also prints JSON.

Why doesn't my hook block when it exits with an error?

Only exit code 2 blocks. Any other error exit is non-blocking, and the action carries on.

Can a hook approve something a deny rule forbids?

No. Claude Code applies deny and ask rules whatever the PreToolUse hook returns.

Where do I configure hooks?

In settings.json at user or project level, in managed settings, in plugins, and in the frontmatter of skills and subagents. Entries from different levels are merged.

Hook or an instruction in CLAUDE.md?

Claude reads CLAUDE.md as context at session start. Anything that must be blocked whatever Claude decides belongs in a PreToolUse hook.

Sources

Further reading

Related articles

Case studies

Related services

Want guardrails on your company's agents?

Tell us which actions your agents take today. We will work out together what should be blocked before it runs.

Write to us