本文へ移動

守るはずの「関所」が、壊れたまま素通りさせていた──Claude Code v2.1.295が“失敗したら止める”を選べるようにした

壊れた安全装置が操作を黙って通す「フェイルオープン」は既定の盲点だった。Claude Code v2.1.294/295が指示文フックの不具合を直し、onFailure:"block"で“失敗したら止める”を選べるようにした要点と、他エージェントとの違い・実運用の設定を整理する。

守るはずの「関所」が、壊れたまま素通りさせていた──Claude Code v2.1.295が“失敗したら止める”を選べるようにした

コーディングエージェントに「危ない操作はここで止めてほしい」と関所(フック)を置く運用が広がっています。ところがその関所が、スクリプトの置き場所を間違えたり、タイムアウトしたりして動かなかったとき、Claude Code はこれまで操作をそのまま通していました。10月8日に出た v2.1.294 と v2.1.295 は、この「壊れたら素通り」を二日がかりで塞ぎ、失敗時に操作を止める挙動を選べるようにしました。

通らないはずの操作が、黙って通っていた

フックは、エージェントがコマンドを実行する前などに割り込んで、ポリシーに反する操作をブロックするための仕組みです。問題は、その割り込み役自身が止まったときの扱いでした。従来の Claude Code は既定でフェイルオープン──フックが起動できない、タイムアウトする、想定外の終了コードを返す、といった場合に、ガードが機能しないまま操作を通していました。

たとえば、ガード用スクリプトのパスを一文字打ち間違えただけで、警告もないまま「無効な安全装置」ができあがります。必要な依存が入っておらず途中で終了コード0(成功)を返してしまえば、本来止めるべき rm -rf のような操作も検問を抜けていきます。関所に見えて、実は開きっぱなしの門だった、というわけです。

二日がかりで塞いだ二つの穴

修正は二段階で入りました。

  • v2.1.294: 「〜なコマンドをブロックせよ」のように指示文で書かれた prompt / agent フックが、本来ブロックすべき操作を通してしまう不具合を修正。あわせて Stop・SubagentStop の指示文フックの判定を見直し、作業が早すぎるタイミングで止まってしまう挙動も減らしました。
  • v2.1.295: command フックと HTTP フックに onFailure: "block" を追加。フックが起動できない・タイムアウトする・想定外の終了コードを返した場合に、操作を通すのではなくブロックする(フェイルクローズド)挙動を選べるようになりました。

これにより、ガードとしてフックを使うチームは、肝心の関所がクラッシュしたときに黙って全通ししてしまう穴を塞げます。ただし公式には、prompt・agent・MCP ツールのフックはこの保護の対象外とされており、「これらをセキュリティゲートとして使わないこと」と明記されています。

エージェント別・フックが失敗したときの挙動

同じ「フック」でも、壊れたときの既定の振る舞いはツールごとに異なります。導入前に押さえておきたい違いを整理します。

ツール失敗時の既定止める手段
Claude Codeフェイルオープン(通す)onFailure: "block" を付けて明示的に止める(v2.1.295以降)
Cursorフェイルオープン(既定 failClosed: false)フックごとに failClosed: true。権限フックはJSONスキーマ検証で不正出力を自動ブロック
Codex通す(未対応フィールドやMCPフックのエラーで処理を継続)フェイルクローズドの切り替えは用意されていない
Gemini CLI終了コード2でブロック、それ以外の非ゼロは警告扱いで続行終了コード2を返す

横断して効く最も確実な書き方は、ガードが自分自身の失敗時に終了コード2で抜けるように作ることです。これなら4つのツールのどれでもブロックに倒せ、バージョンや製品固有の設定に頼らずに済みます。

いますぐ入れておきたい設定

ポリシーを強制する目的のフックには、次の二点を基本にすると取りこぼしが減ります。

  • Claude Code では、ポリシー強制用の command / HTTP フックすべてに onFailure: "block" と短めのタイムアウトを設定する(要 v2.1.295 以降)。
  • スクリプト側は、前提が満たせないときに成功コードで黙って終わらせず、明示的に終了コード2で止める。

逆に、prompt・agent・MCP ツールのフックはセキュリティの最終防衛線には使わない、と割り切るのが安全です。これらは利便性のための補助線として位置づけ、通すか止めるかの判断は command / HTTP フック(+終了コード)に寄せるのが無難でしょう。

自動化が進むほど効いてくる修正

人が「はい/いいえ」を押さなくなり、エージェントが無人で回る場面が増えるほど、関所が静かに壊れていたときの影響は大きくなります。今回の変更は派手な新機能ではありませんが、ガードを「置いたつもり」で安心していた運用にとっては、実害に直結しうる穴をふさぐ地味で重要な一手です。

一方で、フェイルクローズドは「壊れたら止まる」ため、設定を誤れば正常な作業まで止めてしまう副作用もあります。タイムアウト値やブロック対象を欲張りすぎると、かえって開発の流れを止めかねません。関所を厳しくするときは、何を止め何を通すかをログで観察しながら、段階的に締めていくのが現実的です。利便性の裏で安全装置が形だけになっていないか──という問いを、自動化の設計に組み込んでおきたいところです。

参照: Claude Code changelog(公式) / Do Your Agent Hooks Fail Open? Claude Code vs Codex vs Cursor vs Gemini CLI(Developers Digest) / Claude Code 2.1.295 — hooks can fail closed(ai-tldr) / Claude Code Updates(Releasebot)