Claude Media
Claude Codeのスキルのフックは上限あり — 1ソース1,024件・16,384文字

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がそのスキルを呼んだ時点で登録され、そのセッションの残りのあいだ有効です。つまり、呼んだスキルの順に同じソースの合計が増えていきます。

ここから、同じスキルでも動いたり動かなかったりする理由が説明できます。

  • 同じソースの別スキルを先に何本も呼んだセッションでは、あとから呼んだスキルが枠からあふれる
  • 新しいセッションでそのスキルを最初に呼べば、同じスキルのフックが普通に動く

リファレンスはこの回避策も挙げています。作者に修正を頼めないスキルなら、新しいセッションを開き、同じソースのほかのスキルより先に必要なスキルを呼ぶ、というものです。

フックが動かないとき、どの順で切り分けるか

リファレンスの手順に沿うと、次の順で絞れます。

切り分け

スキルのフックが動かないときの切り分け

  1. Qそもそもスキルが呼ばれているか?
    答えが呼ばれていない

    フックはスキルを呼んだ時点で初めて登録されるので、呼ばれていなければ動きません。スキルのトラブルシューティングには、descriptionに利用者が自然に言う言葉を入れる、What skills are available? で一覧に出ているか確かめる、/skill-name で直接呼ぶ、といった確認項目があります。frontmatterのYAMLが壊れていると、本文は読み込まれても説明文が空になり、Claudeが自動で選べなくなります。--debug でパースエラーを見られます。

    答えがはい
  2. Qスキルを呼んだあと、/hooks にそのフックが出るか?
    答えが出ない

    次の問いへ進みます。出る場合は上限の問題ではなく、フックのガイドにある「Hook not firing」の確認項目(matcherの大文字小文字、イベントの種類など)に移ります。

    答えがはい
  3. Q組織の管理設定が strictPluginOnlyCustomization でフックを制限していないか?
    答えが制限していない

    /status の Setting sources に Enterprise managed settings が出ていれば、管理者に確認します。この設定の下では、スキルがプラグイン・組み込み・管理設定ディレクトリのどれかでない限り、frontmatterのフックは効きません。

    答えがはい

件数・文字数の上限を疑う

デバッグログで、上限を超えたスキルを特定します。

/hooks は設定済みフックを読み取り専用で眺めるメニューで、フックごとに出どころ(ユーザー設定、プロジェクト設定、プラグインなど)が表示されます。注意点は、まだ呼んでいないスキルのフックは一覧に出ないことです。フックのガイドも、スキルのフックはまずスキルを呼んでから /hooks を開くよう案内しています。

デバッグログで「上限を超えたスキル」を特定する

上限の確認は、動かなかったセッションを再現して行います。

  1. シェルから claude --debug で新しいセッションを始める(シェルから起動しない場合は、新しいセッションの最初に /debug を入力)
  2. 動かなかったときと同じスキルを、同じ順序で呼ぶ。Claudeが呼んだものも含めて再現する。合計がスキルごとに積み上がるため、順序が違うと再現しない
  3. デバッグログで 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完全ガイドにまとめています。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/hooks
  2. code.claude.com/docs/en/hooks-guide
  3. code.claude.com/docs/en/skills
この記事を共有:XはてブLinkedIn