Claude CodeでWordPressのプラグイン競合を切り分ける — debug.logと二分探索
プラグイン競合の切り分けは、debug.logで容疑者を絞り、wp plugin deactivateの二分探索で確定させる流れで進みます。Claude Codeに渡す材料と権限の切り方を示します。
WordPressのプラグイン競合は、debug.logで疑わしいプラグインを絞り、wp plugin deactivateによる二分探索で犯人を確定させる、という二段で切り分けられます。前半はログの読み解き、後半は同じ操作の繰り返しなので、どちらもClaude Codeに任せやすい作業です。
ただし任せるには、ログを出す設定、渡す材料、実行を許すコマンドの範囲を先に決めておく必要があります。ここでは、その3点を順に整えたうえで、二分探索を手順にします。プラグインそのものの作り方はClaude CodeでWordPressプラグイン開発を始めるにあります。
調査はステージングで行い、ログ出力は4行で足りる
WordPress公式のデバッグ解説は、WP_DEBUGや他のデバッグ機能を本番サイトで使うことを推奨していません。ローカルとステージング向けの機能と位置づけられています。競合の切り分けは、プラグインを実際に無効化する作業でもあります。ステージングか、本番を複製した環境で行います。
ログの出力設定は、wp-config.phpに次の4つの定義を足すだけです。公式の例そのものです。
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );WP_DEBUG_LOGは、エラーをwp-content/debug.logに保存します。値にファイルパスを渡せば保存先を変えられます。WP_DEBUG_LOGもWP_DEBUG_DISPLAYも、WP_DEBUGがtrueでなければ働きません。WP_DEBUG_DISPLAYをfalseにすると画面にはエラーが出ず、ログにだけ残ります。
追記する位置にも決まりがあります。/* That's all, stop editing! Happy blogging.*/の行より前に置きます。公式はこの位置を必須としています。ブール値をクォートで囲んで'false'と書くと、文字列として扱われて真と解釈される点も、公式が注意しています。Claude Codeにwp-config.phpを直させるときは、この2点を指示に含めます。
debug.logとQuery Monitorは、見える範囲が違う
競合の調査に使う材料は2つあり、役割が重なりません。
| 材料 | 見えるもの | 向く切り分け |
|---|---|---|
debug.log | 見えるものPHPのエラー、警告、非推奨通知。Ajaxやwp-cronの実行中に出たものも残る | 向く切り分け致命的エラー、特定のプラグインファイルを指す警告 |
| Query Monitor | 見えるもの遅い・重複・エラーのクエリ、フックとアクション、HTTP API呼び出し、PHPエラーの呼び出し履歴 | 向く切り分け重い、遅い、動作がおかしいのにエラーが出ない競合 |
debug.logは、画面に出せない場面のエラーを拾えるのが強みです。公式は、AJAXリクエストやwp-cronの実行中に出た通知を後から確認できる用途を挙げています。
Query Monitorは、データベースのクエリを、責任のあるプラグイン、テーマ、コア単位でまとめて表示します。遅いクエリ、重複したクエリ、失敗したクエリには通知が付きます。PHPエラーも、責任のあるコンポーネントと呼び出し履歴つきで出ます。エラーが出ないのに遅い、という競合では、こちらが先に手がかりをくれます。
Query Monitorの出力は、既定では単一サイトなら管理者にだけ表示されます。Claude Codeへ渡す方法は2つです。パネルの表示をコピーして貼る方法と、画面のスクリーンショットを貼る方法です。画像はClaude Codeのウィンドウへドラッグ&ドロップするか、Ctrl+Vで貼り付けられます。
CLAUDE.mdと権限で、調査の範囲を固定する
競合調査では、Claude Codeが実際にサイトの状態を変えます。調査の前に、やってよいことと確認が要ることを分けておきます。
まず、プロジェクトのCLAUDE.mdに調査の約束事を書きます。次は一例です。
## WordPress不具合調査のルール
- 作業対象はステージング環境のみ。本番のwp-config.phpは触らない
- プラグインを無効化する前に、有効プラグイン一覧を /tmp/active-before.txt に保存する
- 無効化したプラグインは、再現確認のたびに元へ戻す
- 調査が終わったら WP_DEBUG 系の定義をコメントアウトし、debug.log を空にする
- プラグインの削除(uninstall)とDBの直接変更はしない次に、.claude/settings.jsonで許可するコマンドを絞ります。公式の権限ルールは、Bash(npm run *)のように、*をサブコマンドの後ろに置いて範囲を限る書き方です。
{
"permissions": {
"allow": [
"Bash(wp plugin list *)",
"Bash(wp plugin activate *)",
"Bash(tail *debug.log)"
],
"deny": [
"Bash(wp plugin uninstall *)",
"Bash(wp db *)"
]
}
}wp plugin deactivateはあえてallowに入れていません。wp plugin deactivateには--uninstallオプションがあり、無効化と同時にプラグインをアンインストールできます。許可リストに入れなければ、実行のたびに確認が出ます。確認画面でコマンド全文を見てから通せるので、--uninstallが混じっていないかをその場で見られます。
権限の評価順は、拒否、確認、許可の順です。広い拒否ルールは、より狭い許可ルールがあっても優先します。wp db *を拒否に入れておけば、他の許可ルールがどうあれ、DBの直接操作は止まります。権限の確認や変更の手順は、/permissionsコマンドの解説にまとめています。
debug.logを渡して、容疑プラグインを絞る
準備ができたら、現象を再現してからdebug.logの末尾を渡します。標準入力にログを流して、非対話モードで読ませる書き方が、公式の「Pipe Claude into scripts」の型です。
tail -n 200 wp-content/debug.log | claude -p \
"このログから、エラー元のプラグインをパスごとに集計して"対話モードで進めるなら、再現の手順を一緒に伝えます。公式の「Fix bugs efficiently」にある助言も同じです。再現に使うコマンド、再現の手順、エラーが毎回出るか間欠的かを伝えると、手がかりが増えます。
渡すログの形は、たとえば次のようなものです。以下は形式を示す例で、実際の出力ではありません。
[28-Oct-2026 03:12:45 UTC] PHP Warning: Undefined array key "price" in /var/www/html/wp-content/plugins/acme-shop/inc/cart.php on line 88
[28-Oct-2026 03:12:45 UTC] PHP Fatal error: Uncaught TypeError: ... in /var/www/html/wp-content/plugins/fancy-cache/src/Hook.php:41ここで読み取れるのは、パスに含まれるplugins/直下のディレクトリ名です。acme-shopとfancy-cacheが、エラーを出している側のプラグインです。ただし、エラーを出した場所と、原因を作った場所は同じとは限りません。acme-shopの警告が、別プラグインがフィルターで書き換えた値に起因することもあります。そのため、ログの段階では「疑わしい順位」を付けるところまでにとどめ、確定は次の二分探索に任せます。
Claude Codeへの依頼は、集計と順位付けに絞ると結果が安定します。
wp-content/debug.log を読んで、plugins/ 配下のディレクトリ名ごとに
エラーと警告の件数を出して。件数の多い順に並べ、
最初に出たエラーの行も添えて。原因の推測は別枠にして。wp plugin deactivateの二分探索を手順にする
ログから容疑者が絞れない、あるいは絞れても確証がない場合は、有効なプラグインを半分ずつ無効化して、現象が消える側を探します。12個のプラグインなら、最大でも4回の無効化と再現確認で単独の犯人に届きます。
二分探索の1ラウンド
- 1
有効プラグインの一覧を保存する
最初のラウンドの前に一度だけ、
wp plugin list --status=active --field=nameの出力をファイルに保存します。ここに載るのは有効なプラグインで、must-useは別の区分です。 - 2
半分を無効化する
一覧の前半を
wp plugin deactivateに渡します。複数のプラグインを一度に指定できます。 - 3
現象を再現して結果を見る
同じURLを同じ手順で開き、
debug.logを見ます。エラーが消えれば犯人は無効化した側にいます。残れば、残した側にいます。 - 4
戻して、次の半分へ
無効化した側を
wp plugin activateで元に戻し、犯人がいる側をさらに半分にします。
Claude Codeに回させるときは、再現確認を1本のスクリプトにしておくと結果の判定がぶれません。
# repro.sh: debug.log を空にして対象ページを叩き、エラー件数を数える
: > wp-content/debug.log
curl -s -o /dev/null -w '%{http_code}\n' https://staging.example.test/checkout/
grep -c -E 'PHP (Fatal|Warning)' wp-content/debug.log1ラウンドの操作は次のとおりです。前半6個を試す例で、ステップ1の保存から、再現の確認、元に戻すまでを並べます。
# 1. 有効プラグインを保存(Query Monitor は調査道具なので除く)
wp plugin list --status=active --field=name \
| grep -v '^query-monitor$' > /tmp/active-before.txt
# 2. 前半6個を無効化
head -n 6 /tmp/active-before.txt | xargs wp plugin deactivate
# 3. 再現確認
bash repro.sh
# 4. 元に戻す
head -n 6 /tmp/active-before.txt | xargs wp plugin activateClaude Codeには、この手順を依頼文として渡します。「各ラウンドで、無効化した側、再現確認の結果、次に試す側を1行ずつ報告して」と添えると、判断の過程が追えます。
wp plugin deactivateは、--allで全プラグインを無効化できます。--excludeに除外するスラッグを渡せるオプションもあります。二分探索の半分を--all --exclude=で表現する手もありますが、除外側の指定が長くなります。一覧ファイルのheadとtailで分けたほうが、どちらが残っているかを読み違えにくくなります。
二分探索が効かない競合のパターン
単純な二分探索には、うまくいかない場合があります。
競合が2つのプラグインの組み合わせのとき。どちらの半分を無効化しても現象が消えるなら、組み合わせの2つが別々の半分にいます。この場合は、片方の半分を固定して、もう片方を再び二分します。
依存関係のあるプラグインがあるとき。本体と拡張のように依存する組は、同じ側にまとめて無効化します。拡張だけ残すと、別のエラーが出て現象がすり替わります。
無効化では消えない原因のとき。テーマやmust-useプラグインが原因なら、wp plugin deactivateでは変わりません。WP-CLIのグローバルパラメーター--skip-pluginsは、プラグインの読み込みを飛ばしますが、must-useプラグインは読み込まれます。テーマ側は--skip-themesで飛ばせます。ただしこれらは、WP-CLIの実行時にだけ効く指定で、ブラウザからのリクエストには影響しません。
Query Monitor側の手がかりが要るとき。エラーが出ない遅さは、ログでは捉えられません。Query Monitorのクエリのパネルを、責任のあるコンポーネント別に切り替えると、遅いクエリを出しているプラグインが分かります。フックとアクションのパネルでは、同じフックに登録された処理の順序を確認できます。競合がフックの優先順位に起因する場合の、確証になります。
犯人が分かったあとに、調査用の設定を片づける
犯人が確定したら、元に戻す作業が残ります。CLAUDE.mdに書いた約束事を、チェックリストとして使います。
/tmp/active-before.txtと現在の有効プラグインを突き合わせ、無効化したままのものがないか確認するwp-config.phpのWP_DEBUG系の定義を戻すdebug.logは、サーバーのパスなどが残るため空にするか削除する- 犯人のプラグインについて、設定の見直し、バージョンの更新、代替の検討のどれかを選ぶ
SAVEQUERIESを有効にして調べた場合は、定義を戻すのを忘れないようにします。公式は、これがサイトの性能に影響すると注意しています。
最後に、ここで見つけた競合の再現条件は、CLAUDE.mdに1行残します。「checkoutのページでacme-shopとfancy-cacheが衝突する」のような記録があれば、次回の調査が、ログの絞り込みから始められます。WordPressの規約チェックを自動化する流れはphpcsのhookに、セキュリティ面の洗い出しはnonce・権限・エスケープ漏れの確認にあります。
よくある質問
Query Monitorを入れたまま二分探索をしてよいか
調査道具なので、無効化の対象から外すのが安全です。上の手順ではgrep -vで一覧から除いています。Query Monitor自体の影響は小さいと説明されていますが、クエリが数百件に及ぶページではメモリ使用量が増えると、提供元が書いています。
長時間かかる処理でQuery Monitorの収集を止めたい
Query Monitorはdo_action( 'qm/cease' )を呼ぶと、そのリクエストの残りの間、データ収集を止めます。それまでに集めたデータは破棄されます。大量のクエリを発行する処理の調査で、本題から外れる部分を除くのに使えます。
まとめ
プラグイン競合は、ログで容疑者を絞り、二分探索で確定させます。Claude Codeに任せる価値が大きいのは、ログの集計と、同じ手順の反復です。一方で、wp plugin deactivateの確認を残し、uninstallとwp dbを拒否に入れる設計が、安全に任せる条件になります。再現条件の記録まで済ませると、同じ競合に当たった次回の調査が短くなります。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。