Claude Codeのスキルのフックは上限あり — 1ソース1,024件・16,384文字
v2.1.304から、スキルのfrontmatterに書いたフックには1ソースごとの上限がかかります。1,024件とmatcher合計16,384文字で、超えるとスキルは全フックなしで動きます。
Claude Code v2.1.304以降では、スキルのfrontmatterに書いたフックに上限があります。1つのソースのスキルが登録できるのは最大1,024件で、そのmatcherの文字数は合計16,384文字までです。超えたスキルは、フックを1つも登録せずに動きます。
スキルを呼んだのに自作のフックが走らない。そのとき疑う原因は、frontmatterの書式ミス、組織の管理設定による制限、この件数・文字数の上限の3つです。上限の数え方から、近づくと危ない水準、起きたときの切り分けまでをこの順で扱います。
スキルのフックはいつ登録され、いつまで残るか
スキルのfrontmatterには、設定ファイルと同じ書式でフックを書けます。サブエージェントのfrontmatterにも同じ形で書けますが、寿命が違います。
- スキルのフック: あなたかClaudeがそのスキルを呼んだ時点で登録され、セッションが終わるまで走り続ける。スキル自身のターンが終わったあとのターンでも有効
- サブエージェントのフック: そのサブエージェントが動いている間だけ有効で、終わると外れる。
StopフックはSubagentStopに読み替えられる
スキルのフックは「呼んだ瞬間に登録される」ので、スキルを一度も呼んでいなければ何も登録されていません。次の節の上限が「呼んだ順に積み上がる」のも、この仕組みの帰結です。1回きりで外したいフックには once: true を付けられます。
書き方は次のとおりです。Bash を実行する前にスクリプトで検査する例です。
---
name: secure-operations
description: Perform operations with security checks
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/security-check.sh"
---プロジェクトのスキルに書いたフックは、設定ファイルのフックと同じ、フォルダーのワークスペース信頼のルールに従います。なお -p で信頼していないフォルダーを実行した場合も、スキルを呼べばフックは登録されます。
上限の中身は2つの数字と「ソース」の単位
リファレンスの「Limits on skill hooks」には、次のように書かれています。
スキルのフックの上限(1ソースあたり)
登録できるフック
1,024件
同じソースのスキル全体の合計
matcherの合計
16,384文字
フック1件ごとに数える
数える単位は「ソース」です。プロジェクトの .claude/skills/、個人用のスキルフォルダ、そして各プラグインが、それぞれ別のソースになります。プラグインを10個入れていれば、プロジェクトと個人用を足して12個の別々の枠があるわけです。あるプラグインが枠を使い切っても、ほかのプラグインや自分のスキルには響きません。
もう1つ押さえたいのが、数え方のクセです。1つのmatcherの下に複数のフックをぶら下げると、そのmatcherは「フックの数だけ」文字数に加算されます。次の例では、Write|Edit の10文字が2回数えられ、matcherの消費は20文字です。
hooks:
PostToolUse:
- matcher: "Write|Edit"
hooks:
- type: command
command: "./scripts/format.sh"
- type: command
command: "./scripts/lint.sh"件数と文字数、先に当たるのはどちらか
2つの上限は独立しています。matcherの平均が長いか短いかで、先に当たる側が変わります。
16,384を1,024で割ると16です。この数字は公式の記載ではなく、2つの上限から出した割り算です。フック1件あたりのmatcherが平均16文字を超えると文字数の上限が、下回ると件数の上限が先に来ます。
| matcherの例 | 文字数 | 先に当たる上限 | 目安の件数 |
|---|---|---|---|
Bash | 文字数4 | 先に当たる上限件数 | 目安の件数1,024件(4,096文字) |
Write|Edit | 文字数10 | 先に当たる上限件数 | 目安の件数1,024件(10,240文字) |
Write|Edit|MultiEdit | 文字数20 | 先に当たる上限文字数 | 目安の件数819件(16,380文字) |
表の「目安の件数」は、同じmatcherのフックだけを積んだと仮定した計算値です。実際のスキルはmatcherがばらばらなので、この通りにはなりません。それでも、MCPツールを名指しする長いmatcher(mcp__server__tool のような形)を多数持つスキル群では、文字数のほうが先に尽きます。
ふつうに数本のスキルを書く範囲で、1,024件に届くことは考えにくい水準です。問題になるのは、フックを大量に同梱するプラグインや、スキルを何十本も置いたプロジェクトで、そこに別のスキルが次々と加わる場合です。
合計は「呼んだスキル」から積み上がる
この上限はセッション単位で、スキルごとに別々ではありません。リファレンスの手順にも「どちらの合計もスキルごとに積み上がる」とあります。スキルのフックは、あなたかClaudeがそのスキルを呼んだ時点で登録され、そのセッションの残りのあいだ有効です。つまり、呼んだスキルの順に同じソースの合計が増えていきます。
ここから、同じスキルでも動いたり動かなかったりする理由が説明できます。
- 同じソースの別スキルを先に何本も呼んだセッションでは、あとから呼んだスキルが枠からあふれる
- 新しいセッションでそのスキルを最初に呼べば、同じスキルのフックが普通に動く
リファレンスはこの回避策も挙げています。作者に修正を頼めないスキルなら、新しいセッションを開き、同じソースのほかのスキルより先に必要なスキルを呼ぶ、というものです。
フックが動かないとき、どの順で切り分けるか
リファレンスの手順に沿うと、次の順で絞れます。
スキルのフックが動かないときの切り分け
- Qそもそもスキルが呼ばれているか?答えが呼ばれていない答えがはい
フックはスキルを呼んだ時点で初めて登録されるので、呼ばれていなければ動きません。スキルのトラブルシューティングには、descriptionに利用者が自然に言う言葉を入れる、
What skills are available?で一覧に出ているか確かめる、/skill-nameで直接呼ぶ、といった確認項目があります。frontmatterのYAMLが壊れていると、本文は読み込まれても説明文が空になり、Claudeが自動で選べなくなります。--debugでパースエラーを見られます。 - Qスキルを呼んだあと、/hooks にそのフックが出るか?答えが出ない答えがはい
次の問いへ進みます。出る場合は上限の問題ではなく、フックのガイドにある「Hook not firing」の確認項目(matcherの大文字小文字、イベントの種類など)に移ります。
- Q組織の管理設定が strictPluginOnlyCustomization でフックを制限していないか?答えが制限していない答えがはい
/statusのSetting sourcesにEnterprise managed settingsが出ていれば、管理者に確認します。この設定の下では、スキルがプラグイン・組み込み・管理設定ディレクトリのどれかでない限り、frontmatterのフックは効きません。
件数・文字数の上限を疑う
デバッグログで、上限を超えたスキルを特定します。
/hooks は設定済みフックを読み取り専用で眺めるメニューで、フックごとに出どころ(ユーザー設定、プロジェクト設定、プラグインなど)が表示されます。注意点は、まだ呼んでいないスキルのフックは一覧に出ないことです。フックのガイドも、スキルのフックはまずスキルを呼んでから /hooks を開くよう案内しています。
デバッグログで「上限を超えたスキル」を特定する
上限の確認は、動かなかったセッションを再現して行います。
- シェルから
claude --debugで新しいセッションを始める(シェルから起動しない場合は、新しいセッションの最初に/debugを入力) - 動かなかったときと同じスキルを、同じ順序で呼ぶ。Claudeが呼んだものも含めて再現する。合計がスキルごとに積み上がるため、順序が違うと再現しない
- デバッグログで
registers none of its hooksを検索する
claude --debugこの文字列を含む行に、上限を超えたスキルの名前が出ます。そのスキルは、frontmatterのフックを1件も登録しないまま動いています。一部だけ登録される形ではありません。
直し方は「減らす」「短くする」「分ける」
リファレンスの対処は、そのスキル、または同じソースのほかのスキルで、フックを減らすかmatcherを短くすることです。直したら新しいセッションを始めます。自分の手元で打てる手を挙げると、次のようになります。
- 同じmatcherのフックが複数あるなら、1つのスクリプトにまとめて1件にする。matcherはフックの数だけ加算されるので、効果が2倍に出る
- 長いmatcherは、スクリプト側で絞る前提で短く広げる。たとえば
Bashのように短いmatcherを使い、中身の判定はスクリプトに任せる - 全スキルで共通のフックは、スキルのfrontmatterから外して設定ファイルに置く。設定ファイルのフックはこの上限の対象に書かれていません
- 1回きりで足りるフックは
once: trueを付ける。成功すれば登録が外れる。ただしこの指定が効くのはスキルのfrontmatterだけで、設定ファイルでは無視されます
上限を超えた原因が、自分では直せないプラグインにあるなら、作者に直してもらうか、新しいセッションで先にそのスキルを呼びます。プラグインを別に分けて入れる手もありますが、プラグインごとに枠が別になる点を使うには、ソースを実際に分けなければなりません。
似て見える2つの上限は別物
フックまわりには、数字の上限がほかにもあります。混同しやすいので並べておきます。
| 上限 | 対象 | 数字 | 超えたときの挙動 |
|---|---|---|---|
| スキルのフックの上限 | 対象1ソースのスキルのfrontmatter | 数字1,024件・matcher合計16,384文字 | 超えたときの挙動そのスキルはフックを登録しない |
| 同時実行の上限 | 対象同じイベントのpromptフックとagentフック | 数字12件 | 超えたときの挙動13件目以降は順番待ち |
前者は「登録されるかどうか」、後者は「登録されたあとの走り方」の話です。同時実行の上限はClaude Codeのhooks同時実行で詳しく扱っています。管理設定でスキルのフックが止まるケースはstrictPluginOnlyCustomizationの記事にあります。
まとめ
スキルのフックは、プロジェクト、個人用フォルダ、各プラグインというソースごとに、1,024件・matcher合計16,384文字まで登録されます。超えると、そのスキルはフックを1つも登録しません。症状が出たら、/hooks で一覧を見て、管理設定の制限を除き、claude --debug のログで registers none of its hooks を探す順で絞れます。
数値は目安として押さえておけば十分で、実務で効くのは数え方です。matcherはフックの数だけ加算され、合計は呼んだスキルの順に積み上がります。フックを大量に抱えるソースほど、必要なスキルを先に呼ぶ、共通のフックを設定ファイルへ寄せる、といった整理が効きます。この上限が入ったバージョンの全体像はClaude Code v2.1.304のリリースノートにあり、フック全般の設定はHooks完全ガイドにまとめています。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。