Course lesson
Guide Claude Code with Rich PreToolUse Feedback
Guiding Claude Code with rich feedback turns blocked commands into learning opportunities. Return structured JSON with denial reasons and alternatives so Claude self-corrects in real time.
- Duration
- 1 min
- Access
- Free
- Transcript
- Needs source
Guiding Claude Code with rich feedback turns blocked commands into learning opportunities. Return structured JSON with denial reasons and alternatives so Claude self-corrects in real time.
Exit code vs. JSON output
Exit code 2 (lesson 15):
- Blocks tool execution
- Shows error to Claude
- No structured guidance
JSON output (this lesson):
- Blocks with
permissionDecision: "deny" - Provides
permissionDecisionReasonwith clear alternatives - Creates a self-correcting feedback loop
Return structured feedback
Use HookJSONOutput to deny with guidance:
import { type PreToolUseHookInput, type HookJSONOutput } 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")) {
const output: HookJSONOutput = {
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny", // "allow" | "deny" | "ask"
permissionDecisionReason: "echo is not allowed. Always use node -e and console.log instead."
}
}
console.log(JSON.stringify(output, null, 2))
}
}Key fields:
permissionDecision:"allow"(bypass permission),"deny"(block + feedback), or"ask"(prompt user)permissionDecisionReason: Message shown to Claude (for deny) or user (for allow/ask)
See it self-correct
Prompt Claude to use a blocked command:
use echo to echo hello worldSequence:
- Claude attempts
echo - Hook denies with reason: "use node -e and console.log"
- Claude immediately retries with
node -e 'console.log("hello world")' - Command succeeds
Permission decisions
Three options for permissionDecision:
-
"deny"- Block tool + show reason to Claude Use case: Enforce conventions with guidance -
"allow"- Bypass permission system + show reason to user Use case: Auto-approve safe operations -
"ask"- Prompt user for confirmation + show reason Use case: Require manual approval for sensitive operations
Why this pattern works
- Self-correction: Claude learns your conventions in real-time
- Clear guidance: Explains why something's blocked and what to use instead
- No dead ends: Every denial includes the path forward
- Consistent enforcement: Same rules across all sessions
Try it
Prompts:
use echo to echo hello world