ai newsFr., 16. Okt.
EilmeldungClaude Code Updates 2.1.299 bis 2.1.301 verändern das Verhalten von Hooks

Claude Code Updates 2.1.299 bis 2.1.301 verändern das Verhalten von Hooks

Mit den aktuellen Claude-Code-Versionen funktionieren Hooks teils anders als zuvor. Entwickler sollten sieben Punkte prüfen, um Skripte und Automatisierungen am Laufen zu halten.

dev.toFreitag 08:02 · 16.10.DE10 Min. Lesezeit
Bild: dev.to

Seit Claude Code 2.1.299 läuft ein UserPromptSubmit-Hook, bevor dein Skill expandiert, sodass ein Hook, der den Prompt blockiert, nun auch die Shell-Zeilen des Skills stoppt. Niemand hat deine Hooks-Datei angefasst, um das zu bewirken.

Drei Releases sind am 14. und 15. Oktober 2026 erschienen: 2.1.299, 2.1.300 und 2.1.301 (Changelog). Sieben Zeilen in ihren "Changed"-Abschnitten ändern das Verhalten von Hooks, die du bereits verwendest. Sie verschieben, wann ein Prompt-Hook läuft, was mit Eingaben geschieht, die ein Hook umschreibt, welche MCP-Tools die tools:-Liste eines Agenten aufnimmt, und was ein Plugin-Hook tut, wenn er nicht antworten kann. Keine dieser Änderungen wartet auf eine Anpassung deinerseits. Sie greifen, sobald du die neue Version verwendest.

Jeder der folgenden Punkte zitiert die Changelog-Zeile, erläutert, was dabei brechen kann, und nennt einen Befehl, mit dem du prüfen kannst, ob dein Setup betroffen ist. Zwei Hook-Änderungen aus derselben Woche wurden bewusst ausgelassen: onFailure: "block" (2.1.295) und die enger gefassten MCP-Allow-Regeln (2.1.299). Für beide需要 mehr Raum, als ein Listenpunkt bietet.

claude --version claude update Vollbildmodus aktivieren Vollbildmodus beenden Jede der sieben Änderungen ist in 2.1.299 oder später enthalten. Wenn claude --version eine ältere Nummer ausgibt, trifft keine der sieben Änderungen bisher auf dich zu, und mit claude update beginnt genau das. Eine der drei Korrekturen am Ende reicht weiter zurück, bis 2.1.294.

Wenn du Claude Code über die Hermes IDE verwendest, die ich entwickle, zeigt der Agent-Picker im ⌘N-Sheet die installierte Version neben jedem installierten Agenten an.

Der Agent-Picker von Hermes 2.3.4: Claude Code (installiert, 2.1.299) ausgewählt, Codex installiert (0.145.0), die anderen unterstützten Agenten als Nicht installiert markiert.

Ab 2.1.299: "UserPromptSubmit-Hooks wurden geändert, sodass sie vor der Expansion eines Skills oder eines benutzerdefinierten Slash-Befehls laufen, sodass ein Hook, der den Prompt blockiert, nun auch dessen eingebettete Shell-Befehle stoppt."

Der Körper eines Skills kann Shell-Zeilen enthalten, geschrieben als! gefolgt von einem Befehl in Backticks. Das Getting-Started-Beispiel in der Skills-Dokumentation führt auf diese Weise git diff HEAD aus. Das "now also stops" im Changelog verrät die alte Reihenfolge: Ein blockierender Hook stoppte den Prompt, aber nicht diese Zeilen.

Was brechen kann: Dein Hook sieht den Prompt nun, bevor der Text des Skills darin enthalten ist. Ein Hook, der den Prompt nach Wörtern durchsucht hat, die nur im Körper eines Skills vorkommen, findet nichts mehr. Für die Expansion selbst gibt es ein separates Ereignis, UserPromptExpansion, das auf den Namen des Befehls passt (Hooks-Referenz).

Um zu sehen, was brechen kann, gib deine UserPromptSubmit-Hooks aus und suche nach Mustern, die nur auf den expandierten Text eines Skills passen:

grep -n -A8 UserPromptSubmit \.claude/settings.json ~/.claude/settings.json Vollbildmodus aktivieren Vollbildmodus beenden Dieser Befehl listet die Skills und Befehle auf, deren Shell-Zeilen ein blockierender Hook nun stoppen kann:

grep -rlF '!`'.claude/skills.claude/commands \ ~/.claude/skills ~/.claude/commands Vollbildmodus aktivieren Vollbildmodus beenden 2. Der eigene UserPromptSubmit-Hook eines Skills wartet einen Prompt lang Ab 2.1.299: "Der UserPromptSubmit-Hook im Front-Matter eines Skills wurde geändert, sodass er erstmals auf den Prompt nach dem läuft, der den Skill aufruft."

Ein Skill kann Hooks in seinem Frontmatter deklarieren. Claude Code registriert sie, wenn der Skill aufgerufen wird, und führt sie für den Rest der Sitzung weiter aus (Hooks-Referenz). Wenn der UserPromptSubmit-Hook deines Skills den Prompt geprüft hat, der ihn aufgerufen hat, etwa /deploy prod, sieht er diesen Prompt nicht mehr. Er beginnt mit dem nächsten.

Wenn die Prüfung beim Aufruf erfolgen muss, verschiebe sie zu UserPromptExpansion in deinen Einstellungen. Die Hooks-Referenz nennt genau diesen Fall: ein Hook, der auf deploy passt und /deploy blockiert, sofern keine Genehmigungsdatei vorhanden ist.

{ "hooks": { "UserPromptExpansion": [ { "matcher": "deploy", "hooks": [ { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/deploy.sh" } ] } ] } } Vollbildmodus aktivieren Vollbildmodus beenden Um die Skills zu finden, die diesen Hook deklarieren:

grep -rln UserPromptSubmit.claude/skills ~/.claude/skills Vollbildmodus aktivieren Vollbildmodus beenden Was ein Hook zurückgibt 3. updatedInput wird validiert, unbekannte Schlüssel werden verworfen Ab 2.1.300: "updatedInput von PreToolUse- und PermissionRequest-Hooks wird jetzt wie Claude eigene Eingaben validiert: unbekannte Schlüssel werden verworfen, und Eingaben, die das Tool ablehnt, verweigern den Aufruf."

Die Hooks-Referenz sagte bereits, dass updatedInput "das gesamte Eingabeobjekt ersetzt, also unveränderte Felder zusammen mit geänderten einschließen". Jetzt greift diese Regel. Ein Hook, der nur das geänderte Feld zurückgibt und ein erforderliches auslässt, oder ein Feld falsch schreibt, übergibt dem Tool eine Eingabe, die es ablehnt, und der Aufruf wird verweigert. Ein Schlüssel, den du für deine eigene Buchhaltung hinzugefügt hast, wird verworfen, bevor das Tool ihn sieht.

Die sichere Form geht von der Eingabe aus, die Claude gesendet hat, und ändert ein Feld. In einem Command-Hook mit jq:

jq '{hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow", updatedInput: (.tool_input + {command: "npm run lint"}) }}' Vollbildmodus aktivieren Vollbildmodus beenden Die Prüfung füttert deinen Hook mit einem Beispielereignis und gibt aus, was er als updatedInput zurückliefert, wo immer es sich in der Ausgabe befindet. Ersetze den Pfad durch dein eigenes Skript:

echo '{"hook_event_name": "PreToolUse", "tool_name": "Bash", "tool_input": {"command": "ls"}}' \ |.claude/hooks/rewrite.sh \ | jq '.. |.updatedInput? // empty' Vollbildmodus aktivieren Vollbildmodus beenden Jeder Schlüssel im ausgegebenen Objekt sollte einer sein, den das Tool akzeptiert, und das Objekt sollte die gesamte Eingabe sein, nicht nur das von dir geänderte Feld.

Ab 2.1.300: "PermissionRequest-Hooks in Cowork-Cloud-Sitzungen wurden geändert: Ein setMode-Update im Allow eines Hooks wird nun ignoriert; der Rest der Genehmigung gilt weiterhin."

Ein PermissionRequest-Hook, der einen Aufruf erlaubt, kann auch updatedPermissions senden, und ein Eintragstyp, setMode, ändert den Berechtigungsmodus, etwa zu acceptEdits (Hooks-Referenz). Cowork kann Aufgaben in der Cloud auf Anthropics Servern ausführen. In diesen Sitzungen gilt die Genehmigung weiterhin, aber der Modus wechselt nicht mehr. Ein Hook, der die erste Bearbeitung genehmigt und die Sitzung auf Accept Edits umgestellt hat, sieht weiterhin Berechtigungsanfragen.

Eine verwandte Zeile in 2.1.299 geht für den Auto-Modus in Cowork-Cloud-Sitzungen weiter: "ein PermissionRequest-Hook kann Shell-Befehle oder Subagenten nicht mehr genehmigen; diese Anfragen warten oder werden abgelehnt." Keine der beiden Zeilen erwähnt lokale Terminalsitzungen.

Die Prüfung findet Hooks, die eine Modusänderung senden:

grep -rn setMode.claude ~/.claude/settings.json ~/.claude/hooks Vollbildmodus aktivieren Vollbildmodus beenden Sieben Änderungen an zwei Tagen, keine davon in deiner Konfigurationsdatei.

Ab 2.1.299: "Agent tools:-Listen wurden geändert, sodass sie nur die Tools des genannten MCP-Servers aufnehmen; ein Server, dessen Name __ enthält, wird als mcp__<gesamter Name>__* aufgelistet."

Die Subagents-Dokumentation besagt, dass mcp__<server> oder mcp__<server>__* in tools: jedes Tool des genannten Servers gewährt. Die Allow-Regel-Zeile im selben Release erklärt die alte Lücke: mcp__a erreichte früher auch einen Server namens a__b oder a_. Agent tools:-Listen wurden in gleicher Weise eingeschrännt. Ein Agent, der stillschweigend die Tools eines zweiten Servers über ein gemeinsames Präfix übernommen hat, verliert sie. Wenn kein Eintrag in seiner Liste mehr zu einem Tool auflöst, schlägt laut Dokumentation der Start des Subagenten meist fehl.

Vergleiche die MCP-Einträge in deinen Agentendateien mit den tatsächlichen Servernamen:

grep -rn 'mcp__'.claude/agents ~/.claude/agents claude mcp list Vollbildmodus aktivieren Vollbildmodus beenden 6. Ein Plugin-Hook, der nicht antworten kann, lehnt nun ab Ab 2.1.299: "Aktionen, die ein Plugin-Hook blockieren kann, werden nun abgelehnt statt durchgelassen, wenn der Hook sie nicht empfangen oder seine Antwort nicht zurückgeben kann; das Ergebnis eines bereits ausgeführten Tools wird zurückgehalten."

Diese Änderung kehrt einen Fehler von offen zu geschlossen um. Wenn ein Plugin-Hook eine Aktion nicht empfangen oder seine Antwort nicht zurückgeben konnte, lief die Aktion zuvor durch. Nun wird die Aktion abgelehnt. Wenn das Tool bereits ausgeführt wurde, bleibt es ausgeführt, und Claude sieht sein Ergebnis nie.

Die Hooks-Referenz besagt, dass claude --debug ein Protokoll nach ~/.claude/debug/<session-id>.txt schreibt. Seit 2.1.296 hinterlassen Command-Hooks bei Tool-Ereignissen, Prompts, SessionStart, Stop und mehreren anderen Ereignissen eine Hooks:-Zeile mit dem Befehl, dem Plugin, aus dem er stammt, falls vorhanden, und dem Ergebnis, endend mit einer Dauer oder mit timed out after <N>ms, cancelled oder failed to start. Führe eine Sitzung mit --debug aus und beginne hier:

grep -hE 'timed out|failed to start' ~/.claude/debug/ *.txt Vollbildmodus aktivieren Vollbildmodus beenden Nur Zeilen, die ein Plugin nennen, zählen, und ein Treffer zeigt dir nur, wo du suchen musst. Ein Hook aus deinen eigenen Einstellungen hat mit dieser Änderung nichts zu tun, und /hooks beschriftet jeden Hook mit seinem Ursprung, sodass du beide unterscheiden kannst. Plugins, die als Mods gebaut sind, schreiben keine Hooks:-Zeilen; beginne dafür im Errors-Tab von /plugin.

Ab 2.1.301: "Der.catch-Handler eines Mod-Hooks wurde geändert, sodass er nur läuft, wenn der Hook wirft oder ein Timeout hat; Ereignisse, die unter den eigenen Aufrufen des Hooks ausgelöst werden, überspringen diesen Hook nun, ohne dessen.catch zu befragen."

Die Mod-Referenz führt in einem.catch-Handler drei Werte für next.error.kind auf: throw, timeout und re-entry, wobei Letzteres für ein Ereignis steht, das aus einem internen Aufruf der Mods-API stammt, den dein eigener Hook gemacht hat. Ab Version 2.1.301 überspringen diese inneren Ereignisse deinen Hook, und dein Handler erfährt nie etwas von ihnen. Ein.catch-Zweig für re-entry ist damit toter Code. Ein Tool-Aufruf, den deine Guard selbst über $.tool.call ausführt, wird weder von dieser Guard noch von ihrem.catch geprüft.

Die Prüfung findet Handler, die dafür noch testen, und validiert anschließend das Mod:

grep -rn 're-entry'./my-mod/hooks claude plugin validate./my-mod Enter fullscreen mode Exit fullscreen mode Drei Korrekturen, die jetzt blockieren, was früher durchging Nicht jede Verhaltensänderung wurde unter "Changed" erfasst. In Version 2.1.294 erlaubten Prompt- und Agent-Hooks, die als Anweisungen geschrieben waren, etwa "Blockiere Befehle, die...", nicht mehr das, was sie blockieren sollten. In 2.1.299 schlugen PreToolUse- und PermissionRequest-Hooks ohne gesetzte Shell unter Windows fehl und fielen offen, wenn Git for Windows nicht installiert war. In 2.1.300 greift ein Agent-Hook, dessen Modell nicht verfügbar ist, auf das Modell des Aufrufers zurück, statt die Aktion zuzulassen (Changelog). Falls eine deiner Guards nie zu greifen schien, greift sie möglicherweise jetzt.

Ich baue Hermes IDE, bewege also diesen Abschnitt mit diesem Wissen im Hinterkopf. Hermes betreibt die eigene Oberfläche von Claude Code in einem echten Terminal, sodass sich /hooks, /plugin und claude --debug genau so verhalten wie überall sonst.

Was Hermes hinzufügt, ist ein Ort, um eine Hook-Änderung zu testen, ohne dein Hauptverzeichnis anzufassen. ⌘N (Strg+Umschalt+N unter Windows und Linux) startet jede Aufgabe auf ihrem eigenen Branch hermes/<name> in ihrem eigenen Worktree. Dieser Worktree enthält eine eigene Kopie jeder getrackten Datei, einschließlich.claude/settings.json,.claude/skills/ und.claude/agents/. Bearbeite dort einen Hook, führe die obigen Prüfungen im Terminal dieser Sitzung aus und bringe die Änderung ein, sobald sie sich korrekt verhält. Zwei Einschränkungen: Hooks in ~/.claude/ werden von jedem Worktree geteilt, und git erstellt einen Worktree aus getrackten Dateien, prüfe also, ob eine nicht getrackte.claude/settings.local.json vorhanden ist, bevor du einem Testlauf vertraust.

Die Befehlsliste über jeder Sitzung zeigt angeheftete und eingebaute Befehle, und seit 2.3.4 auch deine eigenen Befehle und Skills, jeweils mit einer kurzen Beschreibung. So entsteht ein schneller Überblick darüber, welche Punkte die Punkte 1 und 2 betreffen.

Die Aktionsleiste über einer Claude-Code-Sitzung (Prompts, Context 4%, Model, Plan, Review, / Commands) mit geöffneter Commands-Liste: angeheftete Punkte Context, Model, Plan und Review, dann eingebaute Befehle wie Compact, Usage und Diff.

Hermes beantwortet nie eine Berechtigungsanfrage für dich und tippt nie eigenständig in ein Terminal, es fügt also keinen eigenen Entscheidungsträger hinzu: Deine Hooks, deine Berechtigungsregeln und du selbst treffen weiterhin die Entscheidung. Es ist kostenlos, als Quellcode unter BSL 1.1 verfügbar und läuft unter macOS, Windows und Linux. Es steht in keiner Verbindung zu Anthropic, Nous Research oder einem anderen Agent-Anbieter.

Die ersten beiden Änderungen und die Korrektur aus 2.1.294 für Prompt-Hooks liegen an einer gemeinsamen Grenze: dem Prompt-Text, der das Modell erreicht, und wer ihn auf dem Weg dorthin umschreiben darf. Das Blockieren eines Prompts, das Erweitern eines Skills und das Schreiben eines Prompt-Hooks als Anweisung sind alles Prompt Engineering, das nun in einer Konfigurationsdatei erfolgt. Der Prompt Engineering Pocket Guide behandelt die zugrundeliegenden Techniken, von System Prompts bis zur Prompt Injection.

Wenn du die Nachprüfungen auf einem Wegwerf-Branch ausführen möchtest, lade Hermes IDE herunter, und falls sich ein Schritt nicht wie beschrieben verhält, öffne ein Issue auf GitHub.

Automatisch übersetzt. Das Original auf Englisch ist unten aufklappbar.

Original (Englisch) anzeigen

Since Claude Code 2.1.299, a UserPromptSubmit hook runs before your skill expands, so a hook that blocks the prompt now also stops the skill's shell lines. Nobody touched your hooks file to make that happen.

Three releases landed on October 14 and 15, 2026: 2.1.299, 2.1.300 and 2.1.301 ( changelog ). Seven lines in their "Changed" sections alter how hooks you already have behave. They move when a prompt hook runs, what happens to input a hook rewrites, which MCP tools an agent's tools: list picks up, and what a plugin hook does when it can't answer. None of them waits for an edit on your side. They apply as soon as you're on the new version.

Each item below quotes the changelog line, says what it can break, and gives one command to see whether your setup is affected. Two hook changes from the same week are left out on purpose: onFailure: "block" (2.1.295) and the narrower MCP allow rules (2.1.299). Each needs more room than a list item.

claude --version claude update Enter fullscreen mode Exit fullscreen mode Each of the seven changes arrived in 2.1.299 or later. If claude --version prints an older number, none of the seven applies to you yet, and claude update is the moment they start to. One of the three fixes near the end goes back further, to 2.1.294.

If you run Claude Code through Hermes IDE, which I build, the agent picker in the ⌘N sheet shows the installed version next to each agent you have installed.

Hermes 2.3.4's agent picker: Claude Code (installed, 2.1.299) selected, Codex installed (0.145.0), and the other supported agents marked Not installed.

From 2.1.299: "Changed UserPromptSubmit hooks to run before a skill or custom slash command expands, so a hook that blocks the prompt now also stops its embedded shell commands."

A skill's body can carry shell lines, written as! followed by a command in backticks. The getting-started example in the skills docs runs git diff HEAD that way. The changelog's "now also stops" tells you the old order: a blocking hook stopped the prompt, but not those lines.

What can break: your hook now sees the prompt before the skill's text is in it. A hook that searched the prompt for words that only appear inside a skill's body has nothing left to find. For the expansion itself there is a separate event, UserPromptExpansion, which matches on the command's name ( hooks reference ).

To see what can break, print your UserPromptSubmit hooks and look for patterns that only match a skill's expanded text:

grep -n -A8 UserPromptSubmit \.claude/settings.json ~/.claude/settings.json Enter fullscreen mode Exit fullscreen mode This one lists the skills and commands whose shell lines a blocking hook can now stop:

grep -rlF '!`'.claude/skills.claude/commands \ ~/.claude/skills ~/.claude/commands Enter fullscreen mode Exit fullscreen mode 2. A skill's own UserPromptSubmit hook waits one prompt From 2.1.299: "Changed a skill's own front-matter UserPromptSubmit hook to first run on the prompt after the one that invokes the skill."

A skill can declare hooks in its frontmatter. Claude Code registers them when the skill is invoked and keeps running them for the rest of the session ( hooks reference ). If your skill's UserPromptSubmit hook checked the prompt that called it, say /deploy prod, it no longer sees that prompt. It starts with the next one.

If the check has to happen on the invocation, move it to UserPromptExpansion in your settings. The hooks reference gives this exact case: a hook matching deploy that blocks /deploy unless an approval file is present.

{ "hooks": { "UserPromptExpansion": [ { "matcher": "deploy", "hooks": [ { "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/deploy.sh" } ] } ] } } Enter fullscreen mode Exit fullscreen mode To find the skills that declare this hook:

grep -rln UserPromptSubmit.claude/skills ~/.claude/skills Enter fullscreen mode Exit fullscreen mode What a hook hands back 3. updatedInput is validated, and unknown keys are dropped From 2.1.300: "Changed hooks: updatedInput from PreToolUse and PermissionRequest hooks is now validated like Claude's own input: unknown keys are dropped, and input the tool rejects denies the call."

The hooks reference already said updatedInput "Replaces the entire input object, so include unchanged fields alongside modified ones." Now that rule bites. A hook that returns only the field it changed and leaves out a required one, or spells a field wrong, hands the tool input it rejects, and the call is denied. A key you added for your own bookkeeping is dropped before the tool sees it.

The safe shape starts from the input Claude sent and changes one field. In a command hook, with jq:

jq '{hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "allow", updatedInput: (.tool_input + {command: "npm run lint"}) }}' Enter fullscreen mode Exit fullscreen mode The check feeds your hook a sample event and prints what it returns as updatedInput, wherever it sits in the output. Swap in your own script path:

echo '{"hook_event_name": "PreToolUse", "tool_name": "Bash", "tool_input": {"command": "ls"}}' \ |.claude/hooks/rewrite.sh \ | jq '.. |.updatedInput? // empty' Enter fullscreen mode Exit fullscreen mode Every key in the object it prints should be one the tool accepts, and the object should be the whole input, not only the field you changed.

From 2.1.300: "Changed PermissionRequest hooks in Cowork cloud sessions: a setMode update in a hook's allow is now ignored; the rest of the approval still applies."

A PermissionRequest hook that allows a call can also send updatedPermissions, and one entry type, setMode, changes the permission mode, to acceptEdits for example ( hooks reference ). Cowork can run tasks in the cloud, on Anthropic's servers. In those sessions the approval still holds, but the mode no longer moves. A hook that approved the first edit and switched the session to accept edits will keep seeing permission requests.

A related line in 2.1.299 goes further for auto mode in Cowork cloud sessions: "a PermissionRequest hook can no longer approve shell commands or subagents; those prompts wait or are denied." Neither line mentions local terminal sessions.

The check finds hooks that send a mode change:

grep -rn setMode.claude ~/.claude/settings.json ~/.claude/hooks Enter fullscreen mode Exit fullscreen mode Seven changes in two days, none of them in your config file.

From 2.1.299: "Changed agent tools: lists to take only the named MCP server's tools; list a server whose name contains __ as mcp__<whole name>__*."

The subagents docs say mcp__<server> or mcp__<server>__* in tools: grants every tool from the named server. The allow-rule line in the same release spells out the old leak: mcp__a used to also reach a server named a__b or a_. Agent tools: lists got the same narrowing. An agent that quietly picked up a second server's tools through a shared prefix loses them. If no entry in its list resolves to a tool anymore, the docs say the subagent usually fails to launch.

Compare the MCP entries in your agent files with the real server names:

grep -rn 'mcp__'.claude/agents ~/.claude/agents claude mcp list Enter fullscreen mode Exit fullscreen mode 6. A plugin hook that can't answer now refuses From 2.1.299: "Changed actions a plugin hook can block to be refused, not let through, when the hook cannot be handed them or cannot hand back its answer; a tool that already ran has its result withheld."

This one flips a failure from open to closed. When a plugin hook couldn't receive an action or couldn't return its answer, the action used to go through. Now the action is refused. If the tool already ran, it stays run, and Claude never sees its result.

The hooks reference says claude --debug writes a log to ~/.claude/debug/<session-id>.txt. From 2.1.296, command hooks on tool events, prompts, SessionStart, Stop and several other events leave a Hooks: line with the command, the plugin it came from if any, and the outcome, ending in a duration or in timed out after <N>ms, cancelled or failed to start. Run a session with --debug and start here:

grep -hE 'timed out|failed to start' ~/.claude/debug/ *.txt Enter fullscreen mode Exit fullscreen mode Only lines that name a plugin count, and a match only tells you where to look. A hook from your own settings has nothing to do with this change, and /hooks labels each hook with where it comes from, so you can tell the two apart. Plugins built as mods don't write Hooks: lines, so for those, start with the Errors tab in /plugin.

From 2.1.301: "Changed a mod hook's.catch handler to run only when the hook throws or times out; events raised beneath the hook's own calls now skip that hook without asking its.catch."

The mods reference lists three values for next.error.kind in a.catch handler: throw, timeout and re-entry, the last for an event that came from inside a mods API call your own hook made. From 2.1.301, those inner events skip your hook and your handler never hears about them. A.catch branch for re-entry is now dead code. A tool call your guard makes itself through $.tool.call won't be checked by that guard or by its.catch.

The check finds handlers that still test for it, then validates the mod:

grep -rn 're-entry'./my-mod/hooks claude plugin validate./my-mod Enter fullscreen mode Exit fullscreen mode Three fixes that now block what used to pass Not every behavior change was filed under "Changed." In 2.1.294, prompt and agent hooks written as instructions, such as "Block commands that...", stopped allowing what they should block. In 2.1.299, PreToolUse and PermissionRequest hooks that set no shell stopped failing open on Windows when Git for Windows isn't installed. In 2.1.300, an agent hook whose model is unavailable falls back to the caller's model instead of allowing the action ( changelog ). If a guard of yours never seemed to fire, it may start firing now.

I build Hermes IDE, so weigh this section with that in mind. Hermes runs Claude Code's own interface in a real terminal, so /hooks, /plugin and claude --debug behave the way they do anywhere else.

What Hermes adds is a place to test a hook change without touching your main checkout. ⌘N (Ctrl+Shift+N on Windows and Linux) starts each task on its own hermes/<name> branch in its own worktree. That worktree has its own copy of every tracked file, including.claude/settings.json,.claude/skills/ and.claude/agents/. Edit a hook there, run the checks above in that session's terminal, and land it once it behaves. Two limits: hooks in ~/.claude/ are shared by every worktree, and git builds a worktree from tracked files, so check whether an untracked.claude/settings.local.json is there before you trust a test run.

The Commands list above each session shows pinned and built-in commands, and since 2.3.4 your own commands and skills too, each with a short description. That makes it a quick inventory of what items 1 and 2 touch.

The action bar above a Claude Code session (Prompts, Context 4%, Model, Plan, Review, / Commands) with the Commands list open: pinned Context, Model, Plan and Review, then built-in commands such as Compact, Usage and Diff.

Hermes never answers a permission prompt for you and never types into a terminal on its own, so it adds no decider of its own: your hooks, your permission rules and you still make the call. It is free, source-available under BSL 1.1, and runs on macOS, Windows and Linux. It isn't affiliated with Anthropic, Nous Research or any agent vendor.

The first two changes, and the 2.1.294 fix for prompt hooks, sit at one boundary: the prompt text that reaches the model, and who gets to rewrite it on the way in. Blocking a prompt, expanding a skill and writing a prompt hook as an instruction are all prompt engineering, done in a config file now. The Prompt Engineering Pocket Guide covers the techniques underneath, from system prompts to prompt injection.

If you want to run the rechecks on a throwaway branch, download Hermes IDE, and if a step doesn't behave as described, open an issue on GitHub.

Originaltitel: Claude Code 2.1.299 to 2.1.301 Changed How Your Hooks Behave: 7 Things to RecheckQuelle: dev.to (dev.to). Original öffnen