Build This Now
Build This Now
TastenkürzelStatus Line Guide
Hooks-LeitfadenPlattformübergreifende Hooks für Claude CodeClaude Code Setup-HooksStop HooksSelbstvalidierende Claude Code AgentenClaude Code Session-HooksKontext-Backup-Hooks für Claude CodeSkill-Aktivierungs-HookClaude Code Permission-Hook
speedy_devvkoen_salo
Blog/Toolkit/Hooks/Stop Hooks

Stop Hooks

Stop Hooks verhindern, dass Claude Code einen Turn beendet, solange Tests fehlschlagen, Builds brechen oder Lint rot ist. Vier Enforcement-Muster plus Schutz vor Endlosschleifen.

Hören Sie auf zu konfigurieren. Fangen Sie an zu bauen.

SaaS-Builder-Vorlagen mit KI-Orchestrierung.

Published Feb 25, 2026Toolkit hubHooks index

Problem: Claude schließt eine Antwort ab, aber die Arbeit ist eigentlich nicht fertig. Tests schlagen noch fehl. Dateien sind halb geschrieben. Du fragst "bist du fertig?" und bekommst ein Ja, während der Build rot ist.

Quick Win: Wirf diesen Stop Hook rein, und Claude kann den Turn nicht beenden, bis alle Tests grün sind:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python .claude/hooks/test-gate.py"
          }
        ]
      }
    ]
  }
}
#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
# CRITICAL: Prevent infinite loops
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
# Run tests
result = subprocess.run(['npm', 'test'], capture_output=True, timeout=60)
 
if result.returncode != 0:
    output = {
        "decision": "block",
        "reason": "Tests are failing. Fix them before completing."
    }
    print(json.dumps(output))
    sys.exit(0)
 
sys.exit(0)

Ab jetzt kann Claude einen Turn mit einer fehlschlagenden Test-Suite schlicht nicht mehr abschließen.

Wie der Stop Hook funktioniert

Jedes Mal wenn Claude eine Antwort beenden will, feuert dieser Hook. Drei Dinge können passieren:

  1. Stopp erlauben - Exit 0, und der Turn endet sauber.
  2. Stopp blockieren - Gib {"decision": "block", "reason": "..."} zurück, und Claude macht weiter.
  3. Validierungen ausführen - Starte Tests, Checks oder beliebige Scripts.

Das Payload

{
  "session_id": "uuid-string",
  "stop_hook_active": false,
  "transcript_path": "/path/to/transcript.jsonl"
}

Achte auf stop_hook_active. Ein true-Wert bedeutet, Claude befindet sich bereits in einem erzwungenen Weiterlauf-Zustand aus einem früheren Block. Übersiehst du dieses Flag, bekommst du eine unkontrollierbare Endlosschleife.

Muster 1: Test Gate

Hält den Turn offen, bis alle Tests bestehen:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
result = subprocess.run(
    ['npm', 'test', '--passWithNoTests'],
    capture_output=True,
    timeout=120
)
 
if result.returncode != 0:
    # Extract last 10 lines of test output for context
    stderr = result.stderr.decode()[-500:] if result.stderr else ""
    print(json.dumps({
        "decision": "block",
        "reason": f"Tests failing. Output: {stderr}"
    }))
    sys.exit(0)
 
sys.exit(0)

Muster 2: Build-Validierung

Blockiert, bis das Projekt kompiliert:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
result = subprocess.run(
    ['npm', 'run', 'build'],
    capture_output=True,
    timeout=180
)
 
if result.returncode != 0:
    print(json.dumps({
        "decision": "block",
        "reason": "Build failed. Fix compilation errors before completing."
    }))
    sys.exit(0)
 
sys.exit(0)

Muster 3: Lint-Check

Kein Verlassen des Turns mit Lint-Fehlern:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
result = subprocess.run(
    ['npx', 'eslint', 'src/', '--max-warnings=0'],
    capture_output=True,
    timeout=60
)
 
if result.returncode != 0:
    print(json.dumps({
        "decision": "block",
        "reason": "Lint errors detected. Run eslint --fix or resolve manually."
    }))
    sys.exit(0)
 
sys.exit(0)

Muster 4: Task-Completion-Marker

Den Turn an einem spezifischen Aufgaben-Flag festmachen:

#!/usr/bin/env python3
import json
import sys
from pathlib import Path
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
# Check for incomplete task marker
marker = Path('.claude/incomplete-task')
if marker.exists():
    task_info = marker.read_text().strip()
    print(json.dumps({
        "decision": "block",
        "reason": f"Task incomplete: {task_info}. Finish it before stopping."
    }))
    sys.exit(0)
 
sys.exit(0)

Den Marker zu Beginn der Arbeit setzen:

echo "Implement user authentication" > .claude/incomplete-task

Ihn löschen, wenn der Job erledigt ist:

rm .claude/incomplete-task

Endlosschleifen verhindern

Hier ist, warum das stop_hook_active-Flag so wichtig ist. Ohne es passiert das:

Claude responds → Stop hook fires → "block" → Claude continues
                                            ↓
Claude responds → Stop hook fires → INFINITE LOOP (without flag check)

Das Flag immer zuerst prüfen:

if input_data.get('stop_hook_active', False):
    sys.exit(0)  # Allow stopping, break the loop

Mehrere Checks kombinieren

Ein einziger Hook kann mehrere Gates hintereinanderschalten:

#!/usr/bin/env python3
import json
import sys
import subprocess
 
input_data = json.load(sys.stdin)
 
if input_data.get('stop_hook_active', False):
    sys.exit(0)
 
checks = [
    (['npm', 'run', 'lint'], "Lint errors"),
    (['npm', 'run', 'typecheck'], "Type errors"),
    (['npm', 'test'], "Test failures"),
]
 
for cmd, error_msg in checks:
    result = subprocess.run(cmd, capture_output=True, timeout=120)
    if result.returncode != 0:
        print(json.dumps({
            "decision": "block",
            "reason": f"{error_msg} detected. Fix before completing."
        }))
        sys.exit(0)
 
sys.exit(0)

Wann Stop Hooks sinnvoll sind

Gute Anwendungsfälle:

  • Auf eine grüne Test-Suite warten, bevor "Aufgabe erledigt"
  • Sicherstellen, dass der Build noch kompiliert
  • Lint- und Type-Fehler abfangen
  • Jede eigene Regel dafür, was "fertig" für dich bedeutet

Schlechte Anwendungsfälle:

  • Alles, was länger als das 60-Sekunden-Timeout läuft
  • Checks, die ins Netz gehen und flakig sind
  • Prompts, die eine menschliche Antwort brauchen (keine Interaktion hier)

Konfiguration

In .claude/settings.json einbinden:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python .claude/hooks/stop-validation.py"
          }
        ]
      }
    ]
  }
}

Mehrere Hooks können gleichzeitig, parallel laufen. Ein block von einem einzigen hält Claude am Laufen.

Debugging

Steckt in einer Schleife fest?

  • Prüf nochmal, ob du stop_hook_active ganz oben im Script liest
  • Loggen: echo "stop_hook_active: $stop_hook_active" >> ~/.claude/stop-debug.log

Block kommt nicht an?

  • Das JSON muss genau so aussehen: {"decision": "block", "reason": "..."}
  • Exit Code 0 verwenden, nicht 2. Exit 2 ist für einen anderen Blockierungspfad.

Tests laufen zu lange?

  • Hook-Timeout ist 60 Sekunden
  • Nur eine kleinere Teilmenge ausführen, oder die Suite beschleunigen

Das "Ralph Wilgum"-Muster

Dieses Muster kommt aus der Community und nutzt Stop Hooks, um eine persistente Aufgaben-Schleife zu erzwingen:

  1. Einen Task-Marker zu Beginn der Session setzen
  2. Den Stop Hook blockieren lassen, solange der Marker vorhanden ist
  3. Claude muss den Marker als Beweis für den Abschluss löschen
  4. Kein versehentliches "Ich bin fertig" mehr, während Arbeit noch offen ist

Das Ergebnis: Claude wechselt von Best-Effort zu garantiertem Abschluss.

Nächste Schritte

  • Den Hooks-Guide lesen, um jeden Hook-Typ kennenzulernen
  • Context Recovery einrichten, damit Sessions Kompaktierung überstehen
  • Skill Activation für automatisches Skill-Laden konfigurieren
  • Permission Hooks für Auto-Approval-Flows anschauen

Continue in Hooks

  • Claude Code Setup-Hooks
    Verknüpfe Skripte, Agenten und Docs in Claude Code Setup-Hooks. Ein Befehl führt ein deterministisches Skript aus, übergibt die Ausgabe an einen diagnostizierenden Agenten und protokolliert lebendige Dokumentation.
  • Kontext-Backup-Hooks für Claude Code
    Ein StatusLine-gesteuerter Claude Code Kontext-Backup-Hook. Schreibt strukturierte Snapshots alle 10K Tokens, damit die Auto-Komprimierung nie Fehler, Signaturen und Entscheidungen verschluckt.
  • Plattformübergreifende Hooks für Claude Code
    Plattformübergreifende Claude Code Hooks: Vermeide .cmd-, .sh- und .ps1-Wrapper und rufe node direkt auf, damit eine .mjs-Datei auf macOS, Linux und Windows im Team funktioniert.
  • Hooks-Leitfaden
    Claude Code Hooks von Grund auf: Exit-Codes, JSON-Ausgabe, asynchrone Befehle, HTTP-Endpunkte, PreToolUse- und PostToolUse-Matcher, Produktionsmuster.
  • Claude Code Permission-Hook
    Installiere einen dreistufigen Claude Code Permission-Hook: sofortiges Allow für sichere Aufrufe, sofortiges Deny für gefährliche, LLM-Check für die Grauzone. Kein Skip-Flag.
  • Selbstvalidierende Claude Code Agenten
    Selbstvalidierende Claude Code Agenten: PostToolUse-Lint-Hooks, Stop-Hooks und schreibgeschützte Reviewer-Subagenten in Agentendefinitionen verdrahten, damit fehlerhafte Ausgaben nie ausgeliefert werden.

More from Toolkit

  • Tastenkürzel
    Claude Code keybindings.json konfigurieren: 17 Kontexte, Tastenkombinations-Syntax, Chord-Sequenzen, Modifier-Kombinationen und wie du jeden Standard-Shortcut sofort deaktivierst.
  • Status Line Guide
    Richte eine Claude Code Status Line ein, die Modellname, Git-Branch, Sitzungskosten und Kontextnutzung anzeigt. settings.json-Konfiguration, JSON-Eingabe, Bash-, Python- und Node.js-Skripte.
  • KI-SEO und GEO-Optimierung
    Ein Überblick über Generative Engine Optimization: Wie du dafür sorgst, dass deine Inhalte in ChatGPT-, Claude- und Perplexity-Antworten zitiert werden, statt nur bei Google zu ranken.
  • Claude Code vs Cursor in 2026
    Ein direkter Vergleich von Claude Code und Cursor in 2026: Agentenmodelle, Kontextfenster, Preisstufen und welches Tool zu welchem Entwickler-Workflow passt.

Hören Sie auf zu konfigurieren. Fangen Sie an zu bauen.

SaaS-Builder-Vorlagen mit KI-Orchestrierung.

On this page

Wie der Stop Hook funktioniert
Das Payload
Muster 1: Test Gate
Muster 2: Build-Validierung
Muster 3: Lint-Check
Muster 4: Task-Completion-Marker
Endlosschleifen verhindern
Mehrere Checks kombinieren
Wann Stop Hooks sinnvoll sind
Konfiguration
Debugging
Das "Ralph Wilgum"-Muster
Nächste Schritte

Hören Sie auf zu konfigurieren. Fangen Sie an zu bauen.

SaaS-Builder-Vorlagen mit KI-Orchestrierung.