CLAUDE LABEN
SCIENCE — Claude Scienceがベータ公開され、研究ツールを統合し監査可能な成果物を生成するワークベンチが使えますMODEL — Claude Opus 4.7のfast modeが7月24日に廃止され、Opus 4.8のfast modeへの移行が必要になりますCODE — Claude Code v2.1.195でフルスクリーン時のマウス操作を無効化できるトグルが追加されましたCODE — ハイフン入りのhook matcherが部分一致ではなく厳密一致になるよう修正されましたAGENT — Claude Scienceは調整役エージェントが専門エージェントを呼び出し、引用や計算をレビューする多段構成ですCLOUD — ClaudeがMicrosoft Foundry(Azure)で一般提供され、Azureネイティブで利用できますSCIENCE — Claude Scienceがベータ公開され、研究ツールを統合し監査可能な成果物を生成するワークベンチが使えますMODEL — Claude Opus 4.7のfast modeが7月24日に廃止され、Opus 4.8のfast modeへの移行が必要になりますCODE — Claude Code v2.1.195でフルスクリーン時のマウス操作を無効化できるトグルが追加されましたCODE — ハイフン入りのhook matcherが部分一致ではなく厳密一致になるよう修正されましたAGENT — Claude Scienceは調整役エージェントが専門エージェントを呼び出し、引用や計算をレビューする多段構成ですCLOUD — ClaudeがMicrosoft Foundry(Azure)で一般提供され、Azureネイティブで利用できます
記事一覧/Claude Code
Claude Code/2026-07-01中級

Claude Code をアップデートしたら hook が発火しなくなった — ハイフン入り matcher の厳密一致化(v2.1.195)

Claude Code v2.1.195 でハイフンを含む hook matcher が部分一致から厳密一致に変わり、既存の PreToolUse フックが静かに発火しなくなりました。原因の切り分けと、壊れない matcher の書き方をまとめます。

Claude Code174hooks13トラブルシューティング37matcher自動化64

朝、いつものように差分を確認していて、手が止まりました。

コミット前に必ず走るはずの SwiftLint チェックが、通っていないのです。エラーで止まったのではありません。フックそのものが、一度も動いた形跡なく静かに素通りしていました。

前夜、Claude Code を最新へ上げたばかりでした。動かなくなったのではなく、「何も起きなくなった」。この種の無音の失敗が、いちばん時間を溶かします。

原因は、v2.1.195 で入った hook matcher の挙動変更でした。私と同じように、ハイフンを含む matcher を書いていた方は同じ落とし穴にはまっているかもしれません。切り分けの過程ごと、記録として残しておきます。

何が起きていたか

私の設定では、特定のツール実行に対してだけフックを差し込んでいました。settings.json の該当箇所は、おおよそこういう形です。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          { "type": "command", "command": ".claude/hooks/pre-edit-check.sh" }
        ]
      }
    ]
  }
}

これ自体は問題なく動いていました。問題は、別のプロジェクトで使っていた「独自のツール名」を狙った matcher のほうでした。

MCP 経由のツールには mcp__myserver__run-lint のような、ハイフンを含む名前が付きます。私はそれを狙って、次のように書いていました。

{ "matcher": "run-lint" }

v2.1.194 までは、この run-lintmcp__myserver__run-lint に「部分一致」して発火していました。ところが v2.1.195 で、ハイフンを含む matcher は「厳密一致」として扱われるよう修正されました。

run-lintmcp__myserver__run-lint と完全一致しません。だから、何のエラーも出さずに、ただ一致しなくなったのです。

最初に疑ったこと

順番に、間違った方向を疑いました。参考までに、私がたどった順路を残します。

最初はシェルスクリプトの権限を疑いました。chmod +x を確認し、直接叩いてみると、スクリプト自体は正しく動きます。ここでフック本体の不具合は消えました。

次に疑ったのは JSON の壊れです。settings.json を検証にかけても、構文は正常でした。

三番目に、claude --debug でセッションを起動し、フックの評価ログを追いました。ここで決定的な手がかりが出ます。PreToolUse の評価自体は走っているのに、私の matcher にマッチした hook が「0件」と記録されていたのです。

スクリプトは無事、JSON も無事、評価も走っている。残るのは matcher の一致判定だけ。ここでようやく、前夜のアップデートに意識が向きました。

原因の確定

変更履歴を確認すると、v2.1.195 に「ハイフンを含む hook matcher を部分一致ではなく厳密一致にする」旨の修正が入っていました。

つまり、これまで暗黙に部分一致で拾えていた matcher は、ハイフンをまたぐ瞬間に一致しなくなります。私の run-lint はその典型でした。

厄介なのは、これが「バグ修正」だという点です。以前の部分一致は、意図しないツールまで巻き込む副作用がありました。厳密化は正しい方向の変更です。ただ、既存設定にとっては挙動が変わる破壊的変更であり、しかもエラーを出さないため、気づくのが遅れます。

自分の設定が古い暗黙の挙動に依存していた、というのが結論でした。

解決策

対処は明快です。matcher を、実際のツール名に対して正しくマッチする形へ書き直します。選択肢は主に三つあります。

一つ目は、ツール名を厳密に書ききる方法です。もっとも安全で、意図も明確になります。

{ "matcher": "mcp__myserver__run-lint" }

二つ目は、正規表現で狙う方法です。MCP ツールをサーバー単位でまとめて拾いたいときに向きます。

{ "matcher": "mcp__myserver__.*" }

三つ目は、ワイルドカードで MCP ツール全体を対象にする方法です。範囲は広くなるので、フック側で本当に処理すべきか判定するのが前提になります。

{ "matcher": "mcp__.*" }

私は一つ目を採りました。狙ったツールが一つだけなら、名前を書ききるのが誤爆もなく読みやすいためです。書き換えた後、claude --debug で該当ツールを実行し、評価ログに hook が「1件」と出ることを確認しました。ここまで見て、ようやく安心できました。

念のため、修正前後の挙動を整理します。

matcher の記述v2.1.194 までv2.1.195 以降
run-lintmcp__myserver__run-lint に部分一致(発火)一致せず(発火しない)
mcp__myserver__run-lint一致(発火)一致(発火)
mcp__myserver__.*一致(発火)一致(発火)

ハイフンを含まない EditWrite のような標準ツール名は、今回の変更の影響を受けません。影響が出るのは、ハイフンをまたいで部分一致に頼っていた matcher だけです。

再発を防ぐために

同じ無音の失敗を二度踏まないよう、運用側でいくつか手を打ちました。

まず、matcher は「部分一致に頼らず、ツール名を厳密に書く」ことを原則にしました。省略形は一見便利ですが、暗黙の一致仕様に寄りかかる分だけ、アップデートで足元をすくわれやすくなります。

次に、フックが「本当に発火したか」をログに残すようにしました。スクリプトの冒頭で標準エラーへ一行書き出すだけでも、素通りしたのか実行されたのかが後から判別できます。

#!/usr/bin/env bash
echo "[pre-edit-check] fired at $(date -u +%FT%TZ)" >&2
# 本来の処理

無音の失敗のいちばんの敵は、失敗が記録に残らないことです。フックが動いた事実そのものを残しておくと、次にアップデートで挙動が変わっても、切り分けの起点になります。

最後に、Claude Code をアップデートしたら、フックが絡む主要な操作を一度だけ手で動かして確認する、という小さな儀式を挟むことにしました。派手ではありませんが、無人で回すパイプラインほど、この確認が効きます。

個人開発で複数のプロジェクトを回している私自身、多くの作業を自動化のフックに預けています。それだけに今回の一件は「便利さのために暗黙仕様へ寄りかかると、静かに壊れる」という教訓として、胸に残りました。

フックの評価ログの読み方そのものに手こずった経験がある方は、Claude Code フックの本番デバッグ手法も合わせて参考になるかもしれません。matcher の書き方から丁寧に押さえたい場合はClaude Code フック完全ガイドを、アップデート起因の別の不具合についてはClaude Code の自動アップデート失敗の対処をご覧ください。

次に確認すべきこと。お使いの settings.json を開き、matcher にハイフンを含む文字列を部分一致で使っていないか、一度だけ見直してみてください。該当があれば、厳密なツール名か正規表現に置き換えておくと安心です。

同じ無音の失敗で時間を溶かす方が一人でも減れば嬉しいです。お読みいただきありがとうございました。

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

Claude Code2026-05-18
Claude Code の Bash ツールで cd や export が引き継がれない時の対処
Claude Code の Bash ツールで cd や export が次のコマンドに反映されない症状の原因と、実務で使える5つの対処パターンを実例とともに整理しました。
Claude Code2026-06-29
Trusted Devices の発想を一人運用に翻訳する — 自動実行を「許可した端末からだけ」に縛る
2026年6月28日に Claude Code へ入った Trusted Devices は Team / Enterprise 向けの端末検証機能です。同じ仕組みは使えなくても、その発想は一人の自動運用に翻訳できます。端末を壊れにくく識別し、許可した端末以外では即座に止める実装を、動くコードとつまずきどころ付きでまとめます。
Claude Code2026-06-28
無人で回す自動処理に、静的 API キーを置きっぱなしにしない — WIF で短命資格情報へ切り替える
Claude Code が静的 API キーを WIF(Workload Identity Federation)の短命・スコープ付き資格情報へ置き換える方向に進んでいます。深夜に無人で回すスケジュール実行で、キー漏れの被害範囲を構造的に小さくする移行手順を、動くコードとつまずきどころ付きで整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →