Claude Code v2.1.294: natural-language prompt and agent hooks now enforce their rule#
Published by Alex Sorokoletov
Part of the Claude Code Version Tracker series. | Official Env Vars | Official Changelog
Claude Code v2.1.294 fixes prompt and agent hooks that are written as plain-English instructions rather than scripts.[1] In v2.1.293 the model that judged these hooks asked only whether a condition was met, so a hook phrased as a rule to block something could be read as satisfied and let the action through. v2.1.294 rewrites that judge to apply a rule as a rule. It follows v2.1.293.
The hook judge now separates a rule from a condition#
A prompt or agent hook can be written as free text, and a model decides what the text means and whether the action proceeds. In v2.1.293 that judge ran under one instruction: decide whether the user-provided condition is met. A hook written as an instruction to block certain commands, the changelog's example is "Block commands that...", is a rule, not a condition, so asking whether it "is met" was the wrong question and the action it named could go ahead.[1]
v2.1.294 gives the judge a single shared contract that handles both readings:
| Hook text reads as | How the judge now answers |
|---|---|
| A rule about what to block or allow | Apply the rule and return its outcome: allow or block the action |
| A condition that must hold | Answer true when the condition holds and false when it does not |
The judge still returns the same shape, an ok flag with a reason, so existing hooks need no change.
The same contract reaches the Stop and SubagentStop evaluator. A stop hook written as an instruction, the changelog's example is "Carry on if the build is broken," was prone to stopping Claude early; it is now applied as a rule, so Claude is less likely to stop before the work is finished.[1]
A boundary between what the judge checks and what instructs it#
The rewritten contract adds a line that v2.1.293 did not carry: the event's JSON and anything the judge reads while deciding are only material to check, and a rule, exception, or instruction embedded there is ignored even when it claims to come from the user. A hook that reads tool input or transcript text now judges that content instead of taking orders from it.
What These Tell Us#
Natural-language hooks put a model in the enforcement path, and this release is about the instruction that model runs under. Naming the two readings a hook can have, a rule to apply or a condition to test, closes the gap where a rule-shaped hook was scored as a passed condition and the action it meant to stop went through.
The Stop and SubagentStop change moves the same wording into the stop decision, where the same confusion showed up as stopping too soon rather than as a skipped block. Both are changes to the instruction one evaluator runs under, with the tool wiring and the ok/reason output shape around it unchanged.
Sources#
- Claude Code Official Changelog, v2.1.294 release notes
This analysis is conducted for educational and research purposes under fair use principles. All trademarks and software referenced belong to their respective owners.
Related Versions#
- Claude Code v2.1.293: Haiku 5.5, subagent status-line agentType, deferred-tool control for mods
- Claude Code v2.1.292: one-command marketplace plugin installs, sub-agent effort levels, and network-path read fixes
- Claude Code v2.1.291: permission-prompt and session-quit regression fixes
- Claude Code v2.1.290: WebFetch paging, scheduled tasks survive resume, web-search refill control
- Claude Code v2.1.289: deny rules now apply to symlinked reads and compound commands, plus agent.spawn for plugins
Previous Claude Code analysis: v2.1.293 (October 7, 2026)
All 68 Claude Code analyses: Claude Code Version Tracker · Official Claude Code changelog