Claude Code の Mod は、読み込みに失敗したり、フックの 1 つが失敗したりしても、そこだけを飛ばしてセッションを続けます。そのため、壊れた Mod は「何も起きない Mod」に見えます。この記事では、Mod が動かないときに、どこから確認し、どの症状がどの原因につながるかを整理します。メッセージの意味は Anthropic の公式ドキュメントのトラブルシューティングに沿っており、validate の出力は Claude Code 2.1.289 で実際に確かめたものです。
先に結論:最初にやる 3 つ
claude plugin validateを実行する:Mod のフォルダを指定すると、マニフェストの誤りとコードの読み取りの失敗を、セッションを起動せずに調べられます。/pluginを開く:タブの下に1 mod active · 名前の行があるか見ます。名前がなければ、Mod は読み込まれていません。- デバッグログを取る:
claude --debug-file ./mod-debug.logで起動すると、読み込んだ Mod、拒否した Mod、失敗したフックのすべてに 1 行ずつ残ります。
1. validate で見つかる誤り
claude plugin validate ./my-mod次のような誤りは、起動する前にここで分かります。
- イベント名の書き間違い:
on('tool.calls', ...)と書くと、"tool.calls" is not an eventというエラーで失敗します。 hooks.jsonにmodulesがない・綴りが違う:modulesをmoduleと書いた私たちの検証では、hooks.json must havehooks(the hook matchers) ormodules(hooks modules), or bothというエラーで失敗しました。hooks:の行が出ない:hooks:の行は、Mod が受け取るイベントの一覧です。そこに期待したイベントがなければ、そのフックは呼ばれません。
validate は、実行はせずに、コードを静的に読みます。書き方の規則($ の呼び出しをそのまま書く、イベント名は文字列リテラル、import は宣言の形で、など)は 初めての Mod の作り方 にまとめました。
2. 症状から探す
何も起きない:コマンドも描画もない
まず /plugin の mods active の行に、Mod の名前があるかを見ます。ない場合は読み込まれていません。次を上から確認してください。
- Claude Code のバージョンが古い:ターミナルは v2.1.287 以降、デスクトップアプリは同梱版が v2.1.286 以降が必要です。
- 初めて開いたディレクトリ:信頼するかどうかの確認に答えるまで、Mod は読み込まれません。そのディレクトリで対話セッションの
claudeを起動し、確認を承認してください。 --safe-modeで起動している:インストールしたプラグインはすべて無効になります。フラグを外してください。- WSL のセッション:デスクトップアプリの WSL セッションでは、プラグインが使えません(動く場所の違い)。
- 設定で止められている:
disableAllHooksや、組織の管理設定が Mod を止めています。次の節の拒否メッセージを見てください。 - Claude が書いた Mod が読み込まれない:最初のファイルの保存時に聞かれるホットリロードの確認が、答えが選ばれないまま 3 回終わると、それ以降は聞かれなくなります(自分で閉じた質問は数えません)。
askUserQuestionTimeoutを設定していて、答える前に時間切れになる場合がこれにあたります。このときは、Mod のフォルダを自分の場所にコピーし、claude --plugin-dirで読み込んでください。
拒否メッセージの読み方
読み込みを拒否されると、デバッグログに hooks module 名前 not loaded: で始まる行が残ります。コロンの後ろが理由です。主なものを表にしました。
| 理由の始まり | 意味 |
|---|---|
hooks modules are turned off for installed plugins in this process: the rollout switch served off | Anthropic が、インストールした Mod を遠隔でオフにしている |
... the rollout switch was saved off by an earlier session | 以前のセッションが保存した値が使われた。古い可能性があるので、Claude Code をもう一度起動する |
disableAllHooks in managed settings | 組織が、インストールしたプラグインのフックを止めている |
only managed plugins and built-in plugins run | allowManagedHooksOnly が設定されている、または、管理設定以外の設定ファイルで disableAllHooks が設定されている |
installed plugins that are not managed load no hooks module in this mode (--bare) | --bare で起動している |
another plugin of that name loads first | 同じ名前のプラグインが 2 つあり、読み込める Mod は名前ごとに 1 つだけ |
組織のガードによる拒否では、mods are limited to your organization's by policy (allowManagedModsOnly) のようなメッセージが出ます。これは、組織が自分たちの Mod だけを許可している状態です。個人の側で直すことはできません(組織で Mods を管理する)。
読み込まれたのに、フックが働かない
/plugin に名前はあるのに、狙った動きにならないときです。
hook skipped:my-mod: tool.call hook skipped: threw Error: boomのような行が出ます。フックが例外を投げた、時間制限(1 つのイベントで 10 秒)を超えた、または正しくない形の結果を返した、のどれかです。同じイベントと原因の組み合わせでは 1 回だけ出ます。デバッグログには、発生のたびに 1 行残ります。registered /x but no command.run hook answered it:/コマンドは登録したのに、答えるフックがない状態です。command.runのフックがない、matcher が別のコマンド名になっている、またはnext(e)を返している、のどれかです。it crashed the hooks worker:インストールした Mod は 1 つのワーカースレッドを共有します。awaitのない無限ループのように、スレッドを塞ぐフックがあると、その Mod が外されます。mods that run in the hooks worker are off for this session:ワーカーが 3 回止まり、原因の Mod を特定できなかったため、内蔵でない Mod が全部外された状態です。/reload-pluginsで読み直せます。
ツール呼び出しが拒否される
a hook changed this call's input after the model wrote it:自動モードで、サーバー側の分類器が確認した後に、フックがツール呼び出しの入力を書き換えたことを示します。同じ呼び出しをもう一度出すように Claude に伝えられますが、それも拒否されるなら、フックが毎回書き換えています。その Mod かフックを止めるか、自動モードをやめて自分で承認してください。tried to lift a deny rule in your settings:あなたの Mod のtool.checkが、denyルールで拒否される呼び出しを許可しようとしました。呼び出しは拒否のままです。
描画が出ない・反応しない
- ペインや帯が空、または Claude Code のいつもの表示のまま:
ui.renderが返した木が検証に通りませんでした。--plugin-dirで読み込んだ場合は、トランスクリプトにui.render (Pane) refused:と理由が出ます。存在しない props や、そのアプリにない要素が典型です。 threw while drawn:木の描画中にエラーが起きました。行の最後にthe engine drew its ownとあれば、その場所は Claude Code の元の表示に戻っています。$.ui.openを呼んだのにペインが出ない:Mod が自分の判断で開いたペインは、端末が 144 桁以上ないと出ません(ユーザーが一度自分で開いた後は 110 桁)。コマンドやボタンから開くか、戻り値のisPlacedを確認してください。- トーストが出ない:デバッグログに
$.ui.toast (名前): 本文の行があるか確かめてください。ほかのペインがholdToastsで保留している、通常の表示で新しいトーストに置き換えられた、全画面表示で 3 つを超えた、などが原因です。 - ホットキーが効かない:ペインにキーボードのフォーカスがありません。Ctrl+X の後に Tab を押すか、ペインをクリックしてください。コマンドから開くときは
focus: trueを付けます。 - ターミナルでは出るのにデスクトップアプリで出ない:その場所や要素が、デスクトップアプリにありません。
編集した内容が反映されない・値が消える
- 編集が反映されない:インストールしたプラグインを編集していませんか。Claude Code は、インストールしたバージョンのキャッシュを動かします。開発中は
claude --plugin-dir ./my-modで作業フォルダを指してください。保存すると読み込み直されます。 - 再読み込みで値が戻る:モジュールの変数は、読み込み直すたびに初期化されます。保持したい値は
$.stateか$.storeに置きます。 /clear、/resume、/branchの後に値が戻る:これらは$.stateをデフォルトに戻し、session.startは再び呼ばれません。classic.SessionStartのフックで、保存した値を読み直します。
3. デバッグログの取り方
claude --debug-file ./mod-debug.log --plugin-dir ./my-mod別のターミナルで、ログを追いながら Mod の名前で絞り込みます。Bash や Zsh では次のとおりです。
tail -f ./mod-debug.log | grep my-modPowerShell では次のとおりです。
Get-Content ./mod-debug.log -Wait -Tail 20 | Select-String my-mod読み込まれた Mod には、名前とイベントを並べた行が残ります。--plugin-dir で読み込んだ Mod は、名前の後ろに @inline が付きます。
hooks module first-mod@inline loaded (worker, environment 2, tier user); events: session.start,tool.call,command.run,ui.render自分のコードからログに書きたいときは、$.ui.log('message', { to: 'debug' }) のように、第 2 引数に { to: 'debug' } を付けます。付けないと、トランスクリプトに暗い 1 行が出ます。保存で再読み込みに失敗すると、reload failed, the previous version stays loaded: と理由が出て、最後に動いた版が動き続けます。
まとめ
動かないときは、validate、/plugin の行、デバッグログの順に見れば、たいていの原因に行き着きます。再現を保つには、自動テストが役に立ちます(Mod のテストの書き方)。コードを書き直す前に、似た実装を探したいときは、ModsCode の MCP が、実際の Mod のコードを返します。原文は 公式のトラブルシューティング にあります。