← Alle Playbooks
Playbook· setup

Hooks against hallucinations

Seven concrete Claude Code hooks that stop the model from inventing things, breaking conventions or running destructive commands.

Hallucinations aren't just a model problem, they're a tool problem. When Claude Code edits files blindly without reading them first, or when it goes for a git push --force on main because you mentioned it once in an early conversation, those are hallucination consequences you can avoid with hooks.

Seven hooks we use at StudioMeyer. All copy-paste-ready, individually toggleable. You don't need a plugin system, everything runs through ~/.claude/settings.json and small bash scripts in ~/.claude/hooks/.

State April 2026, all hooks tested on Claude Code 2.1.x.

1. Read-before-Edit Guard

The problem: Claude Code sometimes edits files without having seen them via the Read tool first. Stella Laurenzo (AMD AI Director) showed in 6852 sessions that the read-to-edit ratio dropped from 6.6 to 2.0, with 33.7 percent blind edits. That leads to files getting torn apart because the model didn't know the existing structure.

The fix: PreToolUse hook that blocks Edit/Write if the target file hasn't been loaded via Read in the session. Bypass via CLAUDE_SKIP_READ_BEFORE_EDIT=1 env var for emergencies.

In ~/.claude/hooks/read-before-edit.sh (pattern see StudioMeyer setup docs in ~/.claude/CLAUDE.md). In ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/read-before-edit.sh" }]
      }
    ]
  }
}

Effect: model MUST call Read before editing. Hallucination edits go to zero.

2. Bash Safety Guard

The problem: Claude Code knows destructive bash commands and can execute them under certain promptings. rm -rf /, git push --force on main, prisma db push --force-reset, DROP DATABASE are the most common traps.

The fix: PreToolUse hook implementing a hard allowlist/blocklist on bash commands. In the script:

#!/usr/bin/env bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')

if echo "$cmd" | grep -qE 'rm -rf /(\s|$)|git push.*--force.*(main|master)|prisma db push.*--force-reset|prisma migrate reset|DROP DATABASE'; then
  echo "BLOCKED: destructive command pattern" >&2
  exit 2
fi
exit 0

In settings.json extend the same PreToolUse block but with "matcher": "Bash". Effect: even if Claude thinks it needs a force-push, it doesn't get through.

3. Sender-Reputation Guard for Mails

The problem: when you send test mails via SMTP/Brevo/Mailgun and the recipient is +-tagged on a domain that rejects plus-addressing (Yahoo, Outlook, GMX, own MX), you generate hard bounces. Six hard bounces in one session, sender reputation broken, all mails go to spam.

The fix: PreToolUse hook that blocks mail-intent bash commands (curl to Brevo, sendmail, swaks) when the recipient address matches a dangerous pattern.

input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')

if echo "$cmd" | grep -qE 'curl.*api.brevo.com|sendmail|swaks'; then
  if echo "$cmd" | grep -qE '\+\w+@(yahoo|outlook|hotmail|gmx|t-online|aol)\.[a-z]{2,3}'; then
    echo "BLOCKED: +tag plus-addressing on hard-rejecting provider. Use MAIL_TEST_OK=1 to bypass." >&2
    exit 2
  fi
fi
exit 0

4. n8n Webhook Side-Effect Guard

The problem: n8n webhooks are often side-effect-heavy. A simple curl https://n8n.studiomeyer.io/webhook/signup actually triggers a welcome mail send because there's a Brevo Send node in the workflow. That cost five hard bounces in one session in April 2026.

The fix: PreToolUse hook that blocks every POST request to n8n.studiomeyer.io/webhook/*. Inspection via GET on /api/v1/workflows/{id} stays allowed.

input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')
if echo "$cmd" | grep -qE 'curl.*-X *POST.*n8n\.studiomeyer\.io/webhook'; then
  echo "BLOCKED: n8n webhook POST. Inspect workflow first via /api/v1/workflows/{id}. Bypass with N8N_TEST_OK=1." >&2
  exit 2
fi

5. Reindex-after-Edit Reminder

The problem: you edit code files, but the codebase memory graph (codebase-memory-mcp) doesn't get re-indexed automatically. Later tool calls return stale data and the model makes decisions on the wrong basis.

The fix: PostToolUse hook that after Edit/Write on code files (.ts, .tsx, .js, .jsx) drops a reindex reminder in the output.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [{ "type": "command", "command": "echo 'Reminder: index_repository if code change'" }]
      }
    ]
  }
}

That's softer than a block: reminder in output, no stop. Still works, because the model sees the reminder list in its context.

6. SessionStart Reminder for Memory + Codebase

The problem: new sessions start without memory context and without codebase index. The model starts guessing instead of looking up.

The fix: SessionStart hook that emits a reminder:

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [{
          "type": "command",
          "command": "echo 'MANDATORY: call nex_session_start + nex_proactive. For code work: index_repository + get_architecture.'"
        }]
      }
    ]
  }
}

The hook output automatically lands in the system context of the first user message. The model sees it before each answer.

7. PreCompact Memory-Snapshot Reminder

The problem: when Claude Code auto-compacts the context (in long sessions), details get lost that haven't been written to memory yet. If you then ask "what did we discuss", you only get what was in the compact summary.

The fix: PreCompact hook that reminds the model just before compact to do a nex_summarize so current knowledge lands in memory before the context shrinks.

{
  "hooks": {
    "PreCompact": [
      {
        "hooks": [{
          "type": "command",
          "command": "echo 'Before compact: call nex_summarize so current decisions/learnings land in memory.'"
        }]
      }
    ]
  }
}

Auto Mode instead of --dangerously-skip-permissions

With Claude Code v2.1.118, --dangerously-skip-permissions is practically dead because there's a much better replacement: Auto Mode. Instead of blindly accepting every permission, Claude Code routes each permission request through a Sonnet-4.6 classifier that distinguishes "harmless" (Read, Glob, the seventh git status) from "potentially expensive" (Bash with rm, external API call, file in ~/.ssh/). Harmless requests get silently approved, the rest land in the user prompt as usual.

In ~/.claude/settings.json:

{
  "autoMode": {
    "enabled": true,
    "classifier": "claude-sonnet-4-6"
  }
}

This replaces the --dangerously-skip-permissions flag for 90 percent of cases. Important: the classifier isn't perfect, so don't rely on it for truly critical paths. Plus: Auto Mode costs a bit (Sonnet calls), but on Max Plan that's flat-rate.

For CI runs or unattended routines where there's really no user around to approve, --dangerously-skip-permissions remains available. But for daily use, Auto Mode is the better default.

Activation order

If you set up these seven hooks, go in this order:

  1. Read-before-Edit Guard (immediately, highest impact)
  2. Bash Safety Guard (immediately, protects against catastrophes)
  3. Sender-Reputation + n8n Webhook Guards (when you trigger mails or workflows)
  4. SessionStart + PreCompact Reminders (quality of life, no risk)
  5. Reindex Reminder (when you use codebase-memory-mcp productively)

Each hook is isolated, you don't need all of them. But 1 and 2 are the ones I honestly don't work without anymore.

Where to find the actual scripts

The snippets shown here are didactically reduced. The production versions belong in your own setup, best documented in your ~/.claude/CLAUDE.md (section "Claude Code Hooks") and wired up in your ~/.claude/settings.json.

What you have after

Seven hooks that together prevent Claude Code from shredding files, executing destructive commands, blowing mails out the window, or using stale codebase data. Setup time is about 30 minutes copy-paste, an hour if you adjust each hook. The first weeks you'll need a few bypasses when you legitimately block something, you adjust iteratively.

All hallucination problems aren't gone. But the most common and expensive are caught.

Hooks against hallucinations — StudioMeyer Academy