タグアーカイブ トラブル解決

GiveWPアップデート後にStripeの寄付が完了しない原因と直し方

GiveWPアップデート後にStripeの寄付が完了しない原因と直し方

Stripeの決済は成功しているのにGiveWPで寄付が「完了」にならない。管理画面に寄付データが作成されず、Webhookだけが延々と失敗し続ける。この症状は、GiveWP 4.16のアップデート後にStripeから送られてくるWebhookの中身が空(null)になっていることが原因だ。PHPの致命的エラー「array_keys(): Argument #1 ($array) must be of type array, null given」が記録されているならなおさらで、GiveWPがイベントデータを正しく読み取れていない。

対処の核心はGiveWPとStripeの接続を完全に再確立し、Webhookの登録から正しくやり直すことにある。加えて、サーバー側のキャッシュがWebhookの受信を阻害しているケースも多いため、キャッシュの全削除とWebhookエンドポイントの除外設定が必要だ。

なぜStripeの決済は成功するのにGiveWPの寄付は未完了になるのか

なぜStripeの決済は成功するのにGiveWPの寄付は未完了になるのか

この問題のややこしい点は、Stripe上では決済が正常に完了して見えることだ。PaymentIntentのステータスは「succeeded」になり、クレジットカードの引き落としも問題なく行われる。しかしGiveWP側では寄付レコードが作成されず、寄付者にも完了メールが届かない。

仕組みをたどると、GiveWPは次の流れで寄付を確定させている。

① 寄付者がフォームで決済を実行
Stripeがクレジットカード情報を処理し、PaymentIntentが作成される
② StripeがWebhookをGiveWPのエンドポイントに送信
エンドポイントURLの例 https://example.com/?give-listener=stripe
③ GiveWPがWebhookを受け取り、署名を検証
署名検証に成功するとイベントデータを内部処理に回す
④ GiveWPが寄付レコードを作成し、ステータスを「完了」に変更
寄付者に完了メールが送信される

この流れのうち、手順③の段階でコケているのが今回の症状だ。StripeからのWebhookはGiveWPのエンドポイントに届いているのに、GiveWPがその中身を処理できない。結果として手順④に進めず、寄付は永遠に「処理中」のまま取り残される。

「array_keys null given」エラーが示す根本原因

「array_keys null given」エラーが示す根本原因

GiveWPのデバッグログに次のような致命的エラーが記録されている場合、原因の特定はかなり絞り込める。

Uncaught TypeError: array_keys(): Argument #1 ($array) must be of type array, null given
in vendor/stripe/stripe-php/lib/StripeObject.php

このエラーは、GiveWPがStripeの公式PHPライブラリ(stripe-php)を使ってWebhookイベントのデータを読み取ろうとしたとき、肝心のイベントオブジェクトの中身がnullになっていることを意味する。本来なら配列として渡されるべきデータが空っぽなのだ。

なぜデータが空になるのか。主な原因は次の3つに集約される。

  • GiveWPのアップデートで内部のWebhook処理ロジックが変わり、既存の接続設定との整合性が崩れた
  • サーバーレベルのキャッシュ(LiteSpeedやホスティング側のキャッシュ)がWebhookリクエストを変形させている
  • StripeダッシュボードのWebhook設定とGiveWPが自動管理する署名シークレットとの間にずれが生じている

4.16より前のバージョンではWebhookのデータ取得方法が異なっていた可能性があり、アップデートによって従来の接続状態に不整合が発生したと見るのが自然だ。事実、GiveWP 4.16がリリースされる直前の6月23日までは正常に動作していたという報告は、この仮説を裏付けている。

GiveWPとStripeの接続を完全に再確立する手順

GiveWPとStripeの接続を完全に再確立する手順

部分的な修正では直らない。GiveWPとStripeの間の信頼関係をゼロから組み直すつもりで、以下の手順を上から順に実行する。

STEP 1 GiveWPを最新バージョンに更新する
4.16.0で問題が発生した場合も、まず4.16.1以降への更新を試みる。GiveWPは不具合修正を迅速にリリースすることが多い。
STEP 2 GiveWP管理画面でStripeとの接続を解除する
「寄付」→「設定」→「支払いゲートウェイ」→「Stripe」から「接続を解除」を実行する。
STEP 3 StripeダッシュボードのWebhookを完全に削除する
Stripeダッシュボードの「開発者」→「Webhook」から、GiveWP用のエンドポイントをすべて削除する。古いものや重複しているものも含めて、すべて消す。
STEP 4 WordPressのキャッシュをすべて削除する
プラグインキャッシュ、サーバーキャッシュ(LiteSpeed等)、ホスティングキャッシュの3層すべてをクリアする。キャッシュ系プラグインを一時的に無効化してもよい。
STEP 5 GiveWPでStripeに再接続する
「寄付」→「設定」→「支払いゲートウェイ」→「Stripe」から「Stripeと接続」を実行し、Stripeの認証画面で許可する。
STEP 6 Webhookが自動再作成されるのを確認する
GiveWPが再接続時にStripeへWebhookエンドポイントを自動登録する。StripeダッシュボードのWebhook一覧を開き、新しいエンドポイントが作成されていること、必要なイベントが有効になっていることを確認する。

GiveWP管理画面でのStripe接続解除と再接続の落とし穴

接続解除ボタンを押しても、内部的に完全にクリーンアップされるとは限らない。GiveWPは接続情報をデータベースのoptionsテーブルに保存しているため、万が一解除がうまくいかない場合は、データベースを直接確認する方法も検討する。

再接続時は必ず本番モードで認証を通すこと。テストモードで接続したあとに本番モードに切り替えても、Webhookエンドポイントはテスト用のものが残ったままになり、本番決済のWebhookが正しく処理されない原因になる。

Stripe Webhookエンドポイントに必要なイベントを確認する

GiveWPが自動登録するWebhookには、以下の8つのイベントが最低限有効になっている必要がある。Stripeダッシュボードでエンドポイントを開き、「受信イベント」欄を目視で確認する。

  • charge.refunded(返金処理)
  • checkout.session.completed(チェックアウトセッション完了)
  • customer.subscription.created(定期寄付の作成)
  • customer.subscription.deleted(定期寄付の削除)
  • invoice.payment_failed(請求書の支払い失敗)
  • invoice.payment_succeeded(請求書の支払い成功)
  • payment_intent.payment_failed(支払い意図の失敗)
  • payment_intent.succeeded(支払い意図の成功)

いずれかが欠けている場合は手動で追加する。GiveWPがイベントを自動追加する仕様はバージョンによって変わるため、再接続後に必ず確認する習慣をつけるとよい。

キャッシュがWebhookを壊す仕組みと確実な対処

キャッシュがWebhookを壊す仕組みと確実な対処

Webhookはサーバー間のHTTP POSTリクエストだ。ところが一部のキャッシュプラグインやホスティング側のキャッシュ機構は、このPOSTリクエストに対して予期せぬ挙動を示す。具体的には、リクエストボディを空にしたり、ヘッダー情報を削除したり、レスポンスをキャッシュしてしまったりする。

GiveWPが正しく署名を検証し、イベントデータを読み取るためには、StripeからのPOSTリクエストが一切加工されずに届かなければならない。次の対応を必ず実施する。

Before(キャッシュがWebhookを加工している状態)
Stripe → キャッシュを通過リクエストボディが変形・空になる → GiveWPが処理失敗
After(キャッシュからWebhookエンドポイントを除外した状態)
Stripe → キャッシュをバイパスリクエストボディが完全なまま届く → GiveWPが正常に処理
キャッシュがリクエストを加工している状態  キャッシュから除外した状態

LiteSpeedキャッシュが原因のケース

LiteSpeedサーバー環境では、LiteSpeed Cacheプラグインの設定画面から「キャッシュ」→「除外」タブを開き、「URLの除外」にGiveWPのWebhookエンドポイントパスを追加する。具体的には「give-listener=stripe」を含むURLパターンを指定する。正規表現が使える場合は次のように記述する。

give-listener=stripe

また、LiteSpeedの「オブジェクトキャッシュ」や「ブラウザキャッシュ」も合わせて無効化した状態でテストすることを推奨する。テストが終わったら再度有効化しても問題はないが、少なくともWebhookエンドポイントだけは常にキャッシュの対象外にしておく。

ホスティング側のキャッシュが原因のケース

一部の共用サーバーやマネージドホスティングでは、サーバーレベルでリバースプロキシキャッシュが動作している。管理パネルからキャッシュを手動でクリアしたあと、一時的にキャッシュ機能を停止してWebhookが正常に処理されるかテストする。

恒常的な解決策としては、ホスティングのサポートに依頼して「https://example.com/?give-listener=stripe」をキャッシュの除外リストに追加してもらう必要がある。

署名シークレットの誤設定が引き起こす症状と修正

署名シークレットの誤設定が引き起こす症状と修正

GiveWP 4.16以降、署名シークレットの管理方法が変わり、手動での設定が不要になった。GiveWPがStripeに接続する際、自動的にWebhookエンドポイントを作成し、署名シークレットもGiveWP内部で管理する。そのため、Stripeダッシュボードから取得した署名シークレットをGiveWPの設定画面に入力する欄は存在しない。

もし過去に手動でWebhookを作成し、その署名シークレットを何らかの方法でGiveWPに設定していた場合、バージョンアップ後にその情報が無視されるか、あるいは競合を起こす可能性がある。そのため、手順としては次のように徹底する。

  1. Stripeダッシュボードから古いWebhookをすべて削除する(手動で作成したものも含む)
  2. GiveWP管理画面でStripeとの接続を完全に解除する
  3. GiveWP管理画面でStripeに再接続する(このとき新しいWebhookと署名シークレットが自動作成される)

署名シークレットに関するエラーがStripeダッシュボードに表示されている場合、ほぼ間違いなく新旧のWebhookが混在しているか、手動設定の名残が残っている。上記の手順で完全にリセットすれば、署名検証エラーは解消する。

それでも直らないときの最終確認リスト

それでも直らないときの最終確認リスト

上記の手順をすべて実行しても症状が改善しない場合、以下のポイントを順に再チェックする。

チェック1 サーバーの時刻が大幅にずれていないか
SSL証明書の評価がAランクでもNTPの同期が外れていると署名検証に失敗する。ホスティングに確認する。
チェック2 .htaccessやNginx設定にWebhookを妨害するルールが入っていないか
特定のクエリ文字列をブロックする設定や、POSTリクエストをGETに変換するリダイレクトルールがないか確認する。
チェック3 セキュリティプラグインがWebhookエンドポイントをブロックしていないか
WordfenceやSucuriなどのWAFがStripeのIPを遮断しているケースがある。一時的に無効化してテストする。
チェック4 StripeのAPIバージョンが極端に新しくなっていないか
Stripeダッシュボードの「開発者」→「APIのバージョン管理」で、使用中のAPIバージョンがGiveWPの対応範囲内か確認する。

よくある質問

GiveWPを最新版に更新したあとにStripeのWebhookが失敗し始めた。ロールバックするべきか

ロールバックは推奨しない。4.16系にはWebhook処理まわりの重要な変更が含まれており、古いバージョンに戻すと将来的にStripe APIの更新に追随できず、より深刻な不具合を引き起こす。まずは本記事の再接続手順を試し、それでも解決しない場合はGiveWPのサポートにシステムレポートを送って調査を依頼するほうが安全だ。

StripeのダッシュボードでWebhookが「失敗」と表示されるが、GiveWP側にエラーログが出ない

GiveWPのデバッグモードが有効になっていない可能性が高い。「寄付」→「設定」→「詳細」→「デバッグモード」を有効にすると、Webhook処理のエラーログが記録されるようになる。ログは「寄付」→「ツール」→「ログ」で確認できる。

再接続してもWebhookがStripeダッシュボードに自動作成されない

GiveWPの接続プロセスの中で、WordPressのREST APIが正しく動作していない可能性がある。パーマリンク設定を「基本」以外に変更して保存し直す。また、セキュリティプラグインがREST APIを制限していないか確認する。

WebhookエンドポイントのURLは手動で変更してもよいか

原則として不要であり、変更すべきではない。GiveWPが自動生成するエンドポイントURLは「https://(サイトURL)/?give-listener=stripe」で固定されており、これをStripeに正しく登録している。URLを手動で変更すると、署名の不一致が発生してすべてのWebhookが失敗する。

GiveWPのシステムレポートはどこで確認できるか

WordPress管理画面の「寄付」→「ツール」→「システム情報」タブを開き、「システムレポートを取得」ボタンをクリックすると、サーバー環境やGiveWPの設定情報がテキスト形式で表示される。サポートに問い合わせる際はこのレポートを添付するとスムーズに調査が進む。

この記事のポイント

  • Stripe決済成功後に寄付が未完了になるのは、Webhook処理の段階でGiveWPがイベントデータを読み取れていないから
  • 致命的エラー「array_keys null given」はWebhookの中身が空であることを示す決定的な手がかり
  • GiveWPとStripeの接続解除からWebhook全削除、再接続までを一気に行い、署名シークレットを完全に再生成する
  • LiteSpeedやホスティングのキャッシュからWebhookエンドポイントを除外し、POSTリクエストが加工されないようにする
  • 署名シークレットはGiveWPが自動管理するため、手動設定は不要であり、むしろ競合の原因になる
404ページがホームページのキャッシュとして表示される原因と修正方法

404ページがホームページのキャッシュとして表示される原因と修正方法

ページキャッシュを有効にしたプラグインで、存在しないはずの404ページにアクセスするとホームページの内容がそのまま表示されてしまう不具合は、該当プラグインのバージョン2.5.0で修正された。管理画面からプラグインを最新版に更新し、キャッシュを全削除すれば解決する。

なぜ404ページがホームページのキャッシュになるのか

なぜ404ページがホームページのキャッシュになるのか

ページキャッシュの仕組みは、最初の訪問者がサイトにアクセスしたタイミングで、その時点のHTML出力をまるごと静的ファイルとして保存する。以降の訪問者には、WordPress本体やデータベースを毎回通さず、この静的ファイルを返すことで表示速度を大幅に上げている。

正常な動作では、訪問者が存在しないURL(いわゆる404ページ)を開いた場合、プラグインはWordPressが「これは404だ」と判定した結果をそのままキャッシュする。もしくは、404ページはそもそもキャッシュの対象から外す設計になっている。しかし今回の事象では、404ページにアクセスした際にWordPressの判定をスキップして、誤ってホームページのキャッシュを返してしまう欠陥がキャッシュ生成処理に含まれていた。

内部の動きを想像で補うと、リクエストが404だとわかった段階でキャッシュを生成せずにスルーすべきところ、テーマやプラグインがフックする前に「URLに対応するキャッシュがないからホームページのキャッシュで代用する」ような分岐に入ってしまっていた可能性が高い。結果として、アドレスバーには存在しないURLが表示されたまま、画面だけホームページのレイアウトという状態が発生する。

Before(不具合発生中)
存在しないURLにアクセスしても、ホームページの画面がそのまま表示される。アドレスバーのURLは404のまま変わらない。
After(修正後)
存在しないURLには、テーマが用意した正しい404ページが表示される。
不具合時の状態  修正後の正常な状態

プラグインをアップデートしてキャッシュを削除する手順

プラグインをアップデートしてキャッシュを削除する手順
STEP 1 管理画面の「プラグイン」から該当プラグインをバージョン2.5.0以降に更新
STEP 2 プラグインの設定画面または専用ボタンから「キャッシュをすべて削除」を実行
STEP 3 ブラウザのシークレットウィンドウで存在しないURLを開き、404表示を確認

アップデートしても直らない場合の追加確認

バージョン2.5.0に更新しキャッシュを全削除したあとも問題が再発するなら、以下の点を順に調べる。

  • プラグインのキャッシュとは別に、サーバー側のVarnishキャッシュやCDNキャッシュが残っていないか
  • 子テーマのfunctions.phpに古いキャッシュ制御コードが残っていないか
  • プラグインの設定で「404ページをキャッシュしない」などの該当オプションが無効になっていないか

アップデート前の一時的な回避策

アップデート前の一時的な回避策

何らかの事情ですぐにプラグインを最新版にできない場合、手元のfunctions.phpにキャッシュ除外用の定数やフックを追加して、404ページをキャッシュ対象から外す一時しのぎが使える。ただしこれはあくまで応急処置であり、根本対応としては必ずアップデートが必要だ。

// 404ページがキャッシュされないようにする一時的な回避策
add_action( 'template_redirect', function() {
    if ( is_404() ) {
        if ( ! defined( 'DONOTCACHEPAGE' ) ) {
            define( 'DONOTCACHEPAGE', true );
        }
    }
});

上記のコードは、WordPressが「このリクエストは404だ」と判定した直後にDONOTCACHEPAGE定数を定義し、該当プラグインのキャッシュ生成を抑止する。テーマのfunctions.phpの末尾、またはCode Snippets系のプラグインで追加する。追加後に改めてキャッシュを全削除すれば、404ページがキャッシュされることを防げる。

ただし定数名はプラグイン固有のものであり、ほかのキャッシュプラグインでも同じ定数が使えるとは限らない。あくまで該当プラグインの一時回避策としてとらえる必要がある。

よくある質問

404ページのキャッシュ問題は特定のテーマが原因になることもあるのか

テーマが独自の404テンプレートを用意している場合でも、基本的には今回のようなバグはプラグインのキャッシュ生成処理に起因する。ただし、テーマが404のときに誤ってホームページと同じクエリを走らせる設計だと、間接的に似た挙動になるケースがありうるため、プラグイン側の問題解決後も念のためテーマの404.phpを確認しておくと安心だ。

キャッシュを削除したのに404ページでホームページが表示され続けるのはなぜか

プラグイン自体のキャッシュだけでなく、ブラウザキャッシュやサーバーレベルのキャッシュ(Varnishやnginx fastcgi cache)、CDNのキャッシュが残っていることが多い。一度シークレットウィンドウでアクセスし、それでも同じならCDNの管理画面からもキャッシュ削除を試す。ホスティングによっては専用のキャッシュクリアボタンが用意されているので確認する。

アップデート後に404表示が直ったが、今後のために404ページをキャッシュさせない設定は必要か

プラグインが正常に404を区別できるようになれば、404ページがキャッシュされることはなくなるため、追加の設定は原則不要だ。むしろ手動で除外設定を重ねると、あとで別の不具合を引き起こす可能性がある。修正が確認できたら、一時回避用のコードは削除しておくほうがよい。

この記事のポイント

  • 404ページがホームページで表示される問題は、該当プラグインのバージョン2.5.0で修正済み
  • 修正後は管理画面からプラグインを更新し、キャッシュをすべて削除すれば解決する
  • 即時更新が難しい場合はfunctions.phpにキャッシュ除外の定数を仕込むことで一時回避できる
  • サーバーやCDNの多段キャッシュが残っていると再発に見えるため、あわせて削除する
Events Manager更新後に公開イベントが下書きに戻る原因と修正

Events Manager更新後に公開イベントが下書きに戻る原因と修正

Events Manager 7.3.7.4 にアップデート後、公開済みイベントの編集画面で「更新」をクリックすると、ステータスが「下書き」に戻ってしまう現象が報告されている。原因は、終日設定のイベントに対してタイムレンジ(時間範囲)が重複してデータベースに登録されてしまうことだ。このバグにより、プラグイン内部のバリデーションが失敗し、自動的に下書きへと巻き戻される。データベースの重複を削除し、プラグインファイルに一時的なパッチをあてることで解決する。

なぜ公開済みイベントが更新時に下書きに戻ってしまうのか

なぜ公開済みイベントが更新時に下書きに戻ってしまうのか

Events Manager はイベントを表す EM_Event クラスが、記事が保存される前に validate_meta() メソッドで内部データの整合性をチェックしている。このチェックに引っかかると wp_insert_post_data フックが介入し、投稿ステータスを強制的に「下書き」に変更する仕様だ。

今回の問題では、「Timeranges cannot overlap with each other.(タイムレンジが重複しています)」というエラーが発生している。しかし、エディタ上では終日(All Day)設定の単一の時間範囲しか表示されていない。実際にデバッグ出力を取得すると、同一イベントに属する同一の終日タイムレンジ(開始 00:00:00、終了 23:59:59)が2件存在しており、これが重複エラーの直接的な原因だ。

データベースで重複したタイムレンジを削除する手順

データベースで重複したタイムレンジを削除する手順
STEP 1 phpMyAdmin でデータベースのバックアップを取得する
STEP 2 重複を検出するSQLクエリを実行する
STEP 3 古い重複行を安全に削除する
STEP 4 イベント編集画面で「更新」して正常化を確認する

STEP 1:必ずデータベースをバックアップする

今回の作業ではデータを直接操作するため、必ず事前にデータベース全体のエクスポートを取得する。何か問題が起きても元に戻せるようにしておこう。

STEP 2:重複タイムレンジを検出する

テーブル名はプラグインの設定により異なるが、多くは wp_em_timeranges となる。phpMyAdmin のSQLタブで次のクエリを実行し、同一 event_id・同一 timerange_starttimerange_end の組み合わせが複数存在しないか確認する。

SELECT event_id, timerange_start, timerange_end, COUNT(*)
FROM wp_em_timeranges
GROUP BY event_id, timerange_start, timerange_end
HAVING COUNT(*) > 1;

結果が返ってきたら、該当の event_id をメモしておく。

STEP 3:重複行のうち一方を削除する

重複している行のうち、より古いIDの行を削除する。以下のクエリは最も小さい ID 以外を削除する例だ。必ず削除対象を SELECT で事前確認してから実行する。

DELETE t1 FROM wp_em_timeranges t1
INNER JOIN wp_em_timeranges t2
WHERE t1.timerange_start = t2.timerange_start
AND t1.timerange_end = t2.timerange_end
AND t1.event_id = t2.event_id
AND t1.ID > t2.ID;

STEP 4:イベントを再編集して正常に保存されるか確認する

データベースの重複を除いたら、WordPress管理画面に戻り、該当のイベント編集画面を開く。内容を微修正して「更新」をクリックし、再び「下書き」に戻らず公開状態が維持されることを確かめる。

プラグインファイルの一時修正で重複登録を防ぐ

プラグインファイルの一時修正で重複登録を防ぐ

根本的な原因は、何らかのトリガーでタイムレンジオブジェクトが二重に追加されてしまうことだ。以下は EM_Event::validate_meta() の中で重複を除去する応急処置のコード例だ。必ずファイルのバックアップを取ったうえで追記する。

// events-manager/classes/em-event.php の validate_meta メソッド内
public function validate_meta( $data, $postarr ) {
    // タイムレンジを取得して重複を排除する
    $timeranges = $this->get_timeranges();
    $unique_timeranges = [];
    foreach ( $timeranges as $timerange ) {
        // timerange_group_id などのキーで一意にする
        $key = $timerange->timerange_group_id . '_' . $timerange->timerange_start . '_' . $timerange->timerange_end;
        if ( ! isset( $unique_timeranges[ $key ] ) ) {
            $unique_timeranges[ $key ] = $timerange;
        }
    }
    // 重複排除済みのコレクションでバリデーション
    if ( ! $unique_timeranges || ! $this->validate_timeranges_collection( $unique_timeranges ) ) {
        // エラー処理...
    }
    // 以下略
}

ただし、このパッチはあくまで暫定的なものだ。プラグインが公式に修正をリリースするまでは、更新のたびに再適用が必要になる。公式サポートフォーラムを定期的に確認し、バグ修正版がリリースされたら速やかにアップデートしよう。

よくある質問

この問題はイベントマネージャーのどのバージョンから発生したのか

少なくとも 7.3.7.4 で報告されている。それ以前のバージョンでは発生していなかった可能性が高いが、同様の重複が偶発的に起きているケースもある。

クラシックエディターを使えば回避できるか

根本原因はデータ保存時のバリデーションにあるため、グーテンベルクエディターかクラシックエディターかは関係ない。ただし、編集画面のUIの違いでトリガーが変わる可能性は否定できない。試す価値はある。

終日イベント以外でも起こるのか

現在報告されているのは終日設定時のケースだ。しかし、時間指定のあるイベントでも重複が起きれば同じエラーで下書きに戻る。該当イベントの編集時は要注意だ。

データベースを直接触らずに直す方法はあるか

現時点では、管理画面から重複を操作できる機能はない。比較的安全な方法としては、一度イベントを複製→元のイベントを削除→複製イベントを公開する、という手順でタイムレンジが正常な状態になることがある。

公式の修正はいつリリースされるのか

これはバグトラッカーや公式フォーラムを見守るしかない。開発チームが認識している問題であれば、次のパッチに含まれる可能性がある。

この記事のポイント

  • Events Manager 7.3.7.4 で発生する既知のバグで、バリデーションエラーによってステータスが下書きに変更される
  • 原因は終日イベントのタイムレンジがデータベース上で重複していること
  • phpMyAdmin から重複行を削除することで一時的に解決する
  • プラグインファイルの修正パッチで再発を防げるが、公式アップデートまでは注意が必要
  • データベース操作前には必ずバックアップを取得する
WordPress更新後にサイトが完全にダウンした時の復旧手順

WordPress更新後にサイトが完全にダウンした時の復旧手順

プラグインやテーマの更新後にサイト全体がダウンし「このサイトで重大なエラーが発生しました」と表示される場合、多くの原因は .htaccess に書き込まれた不適切な指示がサーバー設定と衝突していることにある。FTP / SFTP でサーバーに接続し .htaccess から問題の行を削除するかファイルを一旦削除したあと、WordPress 管理画面でパーマリンク設定を再保存すれば復旧できる。

更新後にサイトが完全にダウンする仕組み

更新後にサイトが完全にダウンする仕組み

一部のプラグインやテーマは、更新時にパフォーマンス向上や URL の取り回しを目的として .htaccess に独自のルールを自動挿入する。これがサーバーの許容範囲を超えると、Apache が起動時に設定ファイルを解釈できず「500 Internal Server Error」を返し、フロントエンドも管理画面もアクセス不能になる。

典型的なのが Option MultiViews のような指示を勝手に追記するケースだ。この機能は Apache のコンテントネゴシエーション(ファイル名の拡張子を自動補完してリクエストを解決する仕組み)を有効にするが、レンタルサーバーや共用ホスティングではセキュリティとルーティングの競合を防ぐために AllowOverride で無効化されていることが多い。許可されていない場所に書かれた Option MultiViews は「ここでは許可されていません」というサーバーエラーを引き起こし、サイト全体を落とす。

WordPress 本体の更新ではこのような追記はほぼ発生しない。問題が起きるのは、更新と同時に .htaccess を操作する一部のキャッシュ系プラグイン、セキュリティ系プラグイン、多言語プラグインだ。プラグイン開発者のテスト環境と本番サーバーの設定が異なるために発生する「動作確認済み」とされる更新でも、自分の環境では致命的になることがある。

.htaccess のエラーでアクセス不能になった時の復旧手順

.htaccess のエラーでアクセス不能になった時の復旧手順
STEP 1 FTP クライアントやサーバーのファイルマネージャでサイトに接続する
STEP 2 WordPress インストールディレクトリ直下の .htaccess をダウンロードしてバックアップする
STEP 3 問題の行(例 Option MultiViews)を削除するか .htaccess を一旦削除する
STEP 4 WordPress 管理画面にログインし「設定」→「パーマリンク」を開いて「変更を保存」をクリックする

FTP 接続と .htaccess の場所を確認する

まずは FTP クライアント(FileZilla など)や契約中のサーバーが提供するファイルマネージャでサーバーに接続する。WordPress をインストールしたディレクトリ(多くの場合は public_htmlhttpdocs)を開き、直下に .htaccess というファイルがあるかを確認する。ドットで始まるファイルはデフォルトで非表示になっている場合があるので、FTP クライアントの設定で隠しファイルを表示するように切り替える必要がある。

エラーログを確認して原因行を特定する(可能な場合)

サーバーのエラーログを見られれば原因の特定は早い。cPanel やコントロールパネルに「エラーログ」または「Error Log」という項目があるので、直近のエントリを確認する。今回のようなケースでは .htaccess: Option MultiViews not allowed here というエラーメッセージが記録されている。この行がログに残っていれば .htaccess 内の Option MultiViews を含む行やブロックを削除するだけで復旧する可能性が高い。

Before(問題のある .htaccess)
# BEGIN WordPress

Option MultiViews

# END WordPress
After(該当行を削除)
# BEGIN WordPress


# END WordPress
エラーを引き起こす行  削除後

.htaccess を削除して WordPress に再生成させる方法

エラーログを確認できない場合や問題の行を特定できない場合は .htaccess を一旦削除してしまうのが手っ取り早い。削除する前に必ずファイルをダウンロードして手元にバックアップを取っておく。削除後、サイトが表示されるようになったら WordPress 管理画面の「設定」→「パーマリンク」を開き、何も変更せずに「変更を保存」ボタンを押す。これで WordPress が必要最小限の .htaccess を自動生成する。

パーマリンク設定を保存して再生成された .htaccess には WordPress の標準ルールだけが書かれているため、問題を引き起こしていた余計な指示は含まれない。この状態でサイトが正常動作していれば復旧成功だ。

原因となったプラグインの特定と対処

.htaccess を修正しても、問題のプラグインをそのままにしておくと再度更新が走ったときや設定変更時に同じことが起きる。更新直前にどのプラグインやテーマを更新したかを確認し、該当するものを一時的に無効化しておく。

管理画面に入れるなら「プラグイン」画面から該当プラグインを停止する。管理画面にも入れない場合は、FTP で /wp-content/plugins/ ディレクトリにアクセスし、該当プラグインのフォルダごと名前を変更する(例: plugin-nameplugin-name-disabled にする)。これでプラグインが強制的に無効化され、管理画面にアクセスできるようになる。

.htaccess を修正しても直らない場合の追加対応

.htaccess を修正しても直らない場合の追加対応

ブラウザキャッシュとサーバーキャッシュをすべて削除する

.htaccess を修正してもまだエラー画面が表示される場合、キャッシュが古いエラー状態を保持している可能性がある。ブラウザのキャッシュを削除し、サーバー側で Varnish や OPcache などのキャッシュ機構が動いている場合はそれらもクリアする。コントロールパネルにキャッシュ管理機能があればそこから削除し、WordPress 用のキャッシュプラグインを導入しているなら FTP で /wp-content/cache/ ディレクトリの中身を手動で削除する。

全プラグインを強制無効化して標準テーマに切り替える

.htaccess の問題ではなく、更新されたプラグインやテーマのコードそのものが PHP の致命的エラーを起こしている可能性もある。FTP で /wp-content/plugins/ フォルダ全体を plugins-temp などにリネームし、使用中のテーマ(/wp-content/themes/テーマ名)もリネームする。WordPress はプラグインがなくても動作し、有効なテーマがない場合は標準テーマ(Twenty Twenty-Five など)に自動でフォールバックする。これで管理画面に入れれば、あとは問題のプラグインやテーマを一つずつ戻して原因を絞り込む。

サーバー会社に AllowOverride 設定を確認する

Option MultiViews のような指示がサーバー側でどう扱われるかは Apache の AllowOverride 設定で決まる。自前で httpd.conf やバーチャルホスト設定を編集できない共用サーバーでは、サーバー会社に「.htaccessOption MultiViews を記述したところサイト全体が停止した。この指示を許可する設定に変更できるか」と問い合わせる手段もある。ただしセキュリティ上の理由で許可されないケースが大半なので、その場合はプラグインの設定を見直すか、代替プラグインを検討する必要がある。

更新による .htaccess 破損を防ぐための対策

更新による .htaccess 破損を防ぐための対策
更新前 必ずサイト全体と .htaccess をバックアップする
更新時 可能ならステージング環境で先にテストする
更新後 即座にサイト全体が表示されるか確認し、問題があれば即座にロールバックする

更新前にかならずバックアップを取る習慣をつける

WordPress 本体、プラグイン、テーマのいずれを更新する場合でも、更新前にサイト全体とデータベースのバックアップを取ることは最も基本的で強力な防御策だ。.htaccess も設定ファイルの一つとしてバックアップ対象に含めておく。バックアップがあれば、今回のようにサイトが完全にダウンしても数分で元の状態に戻せる。

ステージング環境で事前に検証する

本番環境に直接更新を適用する前に、ステージング環境(本番と同一のサーバー設定を持つテストサイト)で動作確認を行うことで、.htaccess の競合や PHP エラーを事前に検出できる。多くの国内レンタルサーバーはコントロールパネルから簡単にステージングサイトを作成できる機能を提供している。少なくとも重要なプラグインのメジャーアップデートでは、このステップを踏むことで大規模なダウンを回避できる。

プラグインの変更履歴を確認し .htaccess 操作の有無を把握する

更新前にプラグインの変更履歴(Changelog)を確認する習慣も有効だ。特に「Improved .htaccess rules」「Added server-level optimizations」などの記述がある場合は要注意で、更新後に .htaccess が書き換わる可能性が高い。こうした更新は必ずバックアップを取ったうえで適用し、適用直後に .htaccess の内容を確認して想定外の追記がされていないかチェックする。

よくある質問

更新後に管理画面だけでなくフロントエンドも真っ白になるのはなぜか

.htaccess のエラーは PHP の処理に入る手前のサーバーレベルで発生するため、WordPress のエラーハンドリング機構が一切働かない。結果としてフロントエンドも管理画面も同じ「500 Internal Server Error」や真っ白な画面になり、WordPress のデバッグモードでもエラーメッセージが表示されないことが多い。

.htaccess を削除しても問題ないのか

WordPress のパーマリンク設定を保存すれば必要なルールは自動で再生成されるので、.htaccess の削除自体は安全だ。ただし独自に追加したリダイレクトルールや BASIC 認証設定などがある場合はバックアップから手動で戻す必要がある。

FTP でサーバーに接続できない場合はどうすればよいか

サーバー会社が提供するコントロールパネル(cPanel など)のファイルマネージャが使えるかを確認する。多くの場合ブラウザから直接ファイルを編集できる。それも使えない状況であればサーバー会社のサポートに連絡し「.htaccess の特定の行を削除してほしい」と依頼するのが最も早い復旧手段になる。

今回のエラーはプラグインの不具合なのか

厳密にはプラグインのコードに問題があるというより、プラグインが想定するサーバー環境と実際のサーバー設定の不一致によって発生する。プラグイン開発者が Option MultiViews が許可されている環境で開発し、許可されていない共用サーバーでエラーが出るケースが典型だ。したがって「不具合」というより環境依存の問題と呼ぶ方が実態に近い。

同じ問題を起こさないために .htaccess をロックできるか

ファイルのパーミッションを 444(読み取り専用)に設定すれば外部からの書き込みは防げるが、WordPress 本体やプラグインが正当な理由で .htaccess を更新する必要がある場合にエラーの原因となる。現実的な対策は、書き換えが発生する更新の前にバックアップを取り、更新後に diff を取って差分を確認する運用だ。

この記事のポイント

  • .htaccess への不適切な追記が更新後のサイトダウンの直接原因になりやすい
  • FTP で問題の行を削除するか .htaccess を一旦削除すれば即座に復旧できる
  • 削除後は管理画面のパーマリンク設定で必要最小限の .htaccess を再生成する
  • 原因プラグインを特定し無効化しないと再発するため忘れずに対処する
  • 更新前のバックアップとステージング検証が最も確実な予防策になる
WooCommerceの税金レポートが表示されない時の原因と直し方

WooCommerceの税金レポートが表示されない時の原因と直し方

WooCommerce の分析「税金」レポートが突然「表示するデータがありません」になった場合、履歴データの再インポートと分析キャッシュのクリアでほぼ解決する。この症状は注文データや収益レポートが正常でも、税金レポートだけが空白になるのが特徴だ。

なぜ税金レポートだけが空白になるのか

なぜ税金レポートだけが空白になるのか

WooCommerce の分析画面は、注文が発生するたびにバックグラウンドで集計テーブルを更新している。しかし、プラグインの更新やサーバーの一時的な負荷、データベースの不整合が重なると、この集計処理が途中で止まることがある。すると注文や収益といった主要レポートは残余データで表示される一方、国別の税金内訳のような細かい集計を必要とするレポートだけが「表示するデータがありません」と出る。

とくに手動で税率を設定している店舗では、税率コードと注文データの突合作業が必要になるため、集計の中断に対して脆弱だ。一時的な不具合であり、データそのものが消失したわけではない。

Before(エラー状態)
税金レポートに「表示するデータがありません」
注文・収益は正常に表示される
履歴データのインポートが「0件中2件」で止まっている
After(正常状態)
国別の税額が一覧表示される
VAT 申告データをそのまま抽出できる
履歴データのインポートが全件完了している
エラー状態  正常状態

履歴データを再インポートして集計を再開する

履歴データを再インポートして集計を再開する

最も確実な解決策は、分析用の履歴データを手動で再インポートすることだ。この操作は既存の注文や顧客データを消さず、集計テーブルだけを再構築する。

STEP 1 管理画面の「分析」→「設定」を開く
STEP 2 ページ下部の「履歴データをインポート」セクションまでスクロール
STEP 3 期間を「すべて」に設定し、「開始」ボタンを押す
STEP 4 インポート完了後、税金レポートを再確認する

「スキップ」チェックボックスに注意する

履歴データのインポート画面には「以前にインポートした顧客と注文をスキップ」というチェックボックスがある。通常はチェックを入れたままでも問題ないが、インポートが途中で止まっている場合は、このチェックを外して全件を再処理するほうが確実だ。件数が多いと時間はかかるが、税金レポートの不整合を解消する近道になる。

インポートが「準備完了」で止まっている場合

履歴データのインポートが「準備完了」と表示され、クリックしても動かない場合は、WooCommerce のスケジュールアクションが滞留している可能性が高い。「WooCommerce」→「ステータス」→「スケジュールされたアクション」を開き、「保留中」のタスクがないか確認する。もし大量に溜まっているなら、WP Crontrol などのプラグインで手動実行するか、サーバーの WP-Cron が正しく動作しているかを調べる必要がある。

分析キャッシュをクリアして表示をリセットする

分析キャッシュをクリアして表示をリセットする

履歴データの再インポートだけで改善しない場合、分析画面が参照しているキャッシュが破損している。WooCommerce には専用のキャッシュクリア機能が用意されている。

  • 管理画面で「WooCommerce」→「ステータス」→「ツール」を開く
  • 「分析キャッシュをクリア」という項目を探す
  • 「実行」ボタンを押す
  • 画面を更新して税金レポートを再表示する

この操作は注文データや設定を一切変更しない。キャッシュを消すだけなので、安全に何度でも実行できる。実行後すぐに改善しない場合は、ブラウザのキャッシュも個別にクリアしてから再確認する。

ブラウザキャッシュとサーバーキャッシュも疑う

分析キャッシュをクリアしても改善しない場合、ブラウザが古い管理画面を表示し続けている可能性がある。シークレットウィンドウで管理画面を開き、同じ症状が出るかを試す。また、サーバー側で Redis や Memcached などのオブジェクトキャッシュを導入している場合は、そちらのキャッシュもクリアする。

データベースツールで直接修復する最終手段

データベースツールで直接修復する最終手段

ここまでの手順で直らない場合、WooCommerce の分析テーブルそのものに不整合が生じている。管理画面の「WooCommerce」→「ステータス」→「ツール」には、分析データベースの検証や修復を行うツールも含まれている。

  • 「分析データベースのテーブルを作成」を実行する(既存テーブルがある場合は何もしない)
  • 「分析データベースのテーブルを検証」を実行し、エラーがあれば修復を試みる

もしこれでも解決しない場合は、ステージング環境(本番とは別のテスト用サイト)に本番のデータを複製し、WooCommerce と WordPress を最新版に更新してから同じ手順を試す。更新によって分析テーブルの構造が修正され、問題が解消することがある。

よくある質問

注文データは消えていないか

消えていない。税金レポートが表示されないのは集計テーブルの不整合であり、実際の注文データは「WooCommerce」→「注文」から確認できる。VAT 申告に必要な情報も、個別の注文画面で確認可能だ。

WooCommerce を更新するのが怖いが、どうすればよいか

WP Staging などのプラグインでステージング環境を作り、そこで先に更新をテストするのが安全だ。問題なければ本番にも反映すればよい。更新を完全に避けるより、検証した上で適用するほうが長期的なリスクは小さい。

手動税率と自動税率のどちらが税金レポートに強いか

WooCommerce Tax 拡張(自動税率)を使うと、税率の管理と集計が一本化されるため、レポートの安定性は上がる。ただし手動税率でも正しく設定されていれば問題なく動作する。今回のように不具合が出たときは、手動税率のほうが原因特定に手間がかかることがある。

分析キャッシュをクリアすると他のレポートに影響するか

影響しない。キャッシュをクリアしても、次回アクセス時に再集計が走るだけだ。むしろ他のレポートでも古いキャッシュによる誤表示が起きていた場合、一括で改善する。

インポートがいつまでも終わらない時の対処法は

注文件数が数万件を超える大規模店舗の場合、インポートに時間がかかることがある。サーバーの PHP 実行時間制限(max_execution_time)が短すぎると途中で停止するため、サーバー管理者に延長を依頼するか、WP CLI を使ってコマンドラインから実行するのが確実だ。

この記事のポイント

  • 税金レポートだけが空白になるのは、集計テーブルの不整合が主な原因
  • 履歴データの再インポートと分析キャッシュのクリアが最も効果的な解決策
  • 「スキップ」チェックを外して全件インポートするとより確実
  • スケジュールアクションの滞留やサーバーキャッシュも併せて確認する
  • どうしても直らない場合はステージング環境で更新をテストする
Advanced Ads 2.0.23 アップデート後の致命的エラーの直し方

Advanced Ads 2.0.23 アップデート後の致命的エラーの直し方

Advanced Ads 2.0.23 にアップデートした途端に「このサイトで重大なエラーが発生しました」と表示される問題は、Pro版のキャッシュバスティング機能が原因だ。管理画面にアクセスできなければ、FTP またはファイルマネージャーでプラグインを手動で一時無効化し、バージョンを 2.0.22 に戻せば即座に復旧する。

なぜ Advanced Ads 2.0.23 で致命的エラーが起こるのか

なぜ Advanced Ads 2.0.23 で致命的エラーが起こるのか

エラーの直接の原因は、Advanced Ads のコアプラグイン側にある abstract-group.php の 170 行目で、Pro版のキャッシュバスティングモジュールから渡された配列データの型を正しく取り扱えず、TypeError が発生している点だ。PHP 8.4 系の厳格な型チェックによって、以前のバージョンでは警告で済んでいた箇所が致命的エラーに変わった。

内部的には、get_ad_weights メソッドが想定するデータ構造と、キャッシュバスティングが上書きしたグループ情報との間で不整合が起きている。とくに広告グループの重み付け配列に対して issetempty でアクセスしようとした際に、オフセットとして配列そのものを渡してしまう形になり、PHP が型エラーを投げている。

Before(エラー状態)
Advanced Ads 2.0.23 + Pro キャッシュバスティング有効
→ 「このサイトで重大なエラーが発生しました」
After(解決後)
Advanced Ads 2.0.22 にロールバック
→ サイトが正常表示される
エラー状態  修正後

上記のデモは、キャッシュバスティング機能が有効な状態でのエラー発生と、プラグインのダウングレードによる復旧の流れを表している。

管理画面にアクセスできない場合の緊急復旧手順

致命的エラーによって WordPress 管理画面にもログインできない状態では、ブラウザ上の操作だけで問題を解消できない。FTP クライアントか、レンタルサーバーのファイルマネージャーを使ってサーバー上のファイルを直接操作する。

FTP またはファイルマネージャーでプラグインを一時無効化する

サーバーに接続したら、/wp-content/plugins/ ディレクトリへ移動する。ここで advanced-ads フォルダと advanced-ads-pro フォルダの名前を変更する。フォルダ名の末尾に -disabled を付与すれば、WordPress はそのプラグインを認識しなくなり、エラーが止まる。

フォルダ名の変更例は次のとおりだ。
advanced-adsadvanced-ads-disabled
advanced-ads-proadvanced-ads-pro-disabled

この状態でサイトのフロントエンドにアクセスすると、致命的エラーは出なくなる。ただし広告が一切表示されない点に注意する。次に管理画面へ入れるようになるので、続けてプラグインのバージョンロールバックを行う。

Advanced Ads をバージョン 2.0.22 に戻す

まず FTP でリネームした advanced-ads-disabled フォルダを元の advanced-ads に戻す。Pro版の advanced-ads-pro-disabled は、まだ無効化されたままにしておく。この操作で Advanced Ads の基本プラグインだけが有効化された状態になる。

管理画面にログインし、「Advanced Ads」→「ツール」→「バージョン管理」へ進む。ここでバージョン 2.0.22 を選択し、ロールバックを実行する。ロールバック完了後、Pro版のフォルダ名を元に戻して有効化すれば、2.0.22 の組み合わせで通常運用に復旧できる。

STEP 1 FTP で advanced-ads フォルダと advanced-ads-pro フォルダをリネーム(末尾に -disabled)
STEP 2 advanced-ads フォルダのみ元の名前に戻す(Pro版は無効のまま)
STEP 3 管理画面「ツール」→「バージョン管理」で 2.0.22 にロールバック
STEP 4 Pro版のフォルダ名も元に戻し、有効化して復旧完了

この一連の手順で、管理画面に入れない状態からでも確実にサイトを復旧できる。

キャッシュバスティングを無効化して一時しのぎする方法

キャッシュバスティングを無効化して一時しのぎする方法

管理画面にアクセスできる状態であれば、Pro版のキャッシュバスティング機能をオフにするだけで致命的エラーを回避できる。Advanced Ads Pro の設定画面を開き、「キャッシュバスティング」セクションのトグルを無効化する。これにより cache-busting.class.php の処理が走らなくなり、エラーの発生箇所が呼び出されない。

無効化後にサイトのフロントエンドを再読み込みして、エラーが消えたことを確認する。この方法はあくまで応急処置であり、根本的な修正が公式から提供されるまではキャッシュバスティング機能を使えない点に留意する。広告のインプレッション計測や表示の最適化に影響が出るため、修正版のリリースを待つか、前述のロールバックを適用するほうが望ましい。

PHP 8.4 環境で注意すべきエラーの傾向

PHP 8.4 では、配列オフセットに対する型の取り扱いがさらに厳格化された。今回のエラーも、Cannot access offset of type array in isset or empty というメッセージにあるとおり、配列を別の配列のキーとして使おうとしたコードがエラーになっている。PHP 7.x 系では E_WARNING で済んでいたコードが、8.x 系では TypeError の致命的エラーに格上げされるケースが増えている。

TagDiv Newspaper のような複合的なテーマとビルダー系プラグインを併用している環境では、テーマが内部的にウィジェットブロックを動的サイドバーとしてレンダリングし、その中で Advanced Ads の広告配置が呼び出される。この呼び出し階層が深いほど、わずかな型の不整合がスタックトレース全体を巻き込む致命的エラーに発展しやすい。エラーログのスタックトレースを読むときは、一番上の発生行だけでなく、そのひとつ下の呼び出し元との関係に着目すると原因特定が早まる。

よくある質問

2.0.23 にアップデートしたあとサイト全体が真っ白になるのは同じ原因か

同じ可能性が高い。とくに Pro版のキャッシュバスティングを有効にしている場合、このエラーが発生する。画面が真っ白になるのは PHP の致命的エラーによって WordPress の表示処理が途中で停止しているためだ。サーバーのエラーログを確認すると、今回と同じ TypeError が記録されているはずだ。

ロールバック機能が管理画面から使えないときはどうすればよいか

FTP でプラグインフォルダをリネームして一時無効化し、コアプラグインだけを有効にして管理画面にアクセスできる状態を作る。そのうえで「バージョン管理」からロールバックを実行する。どうしても管理画面に入れない場合は、WordPress 公式プラグインディレクトリから 2.0.22 の ZIP を手動でダウンロードし、FTP で上書きアップロードする方法でもダウングレードできる。

Pro版のキャッシュバスティングを無効にすると広告収益にどの程度影響があるか

キャッシュバスティングは広告の表示を毎回動的に変えることでキャッシュによる同一広告の連続表示を防ぐ仕組みだ。無効化すると、ページキャッシュが効いた状態では同じ広告が繰り返し表示される可能性が高まり、インプレッションの多様性が下がる。短期的な暫定対処としては許容できるが、修正版リリース後は必ず再有効化するほうがよい。

今回のエラーは Advanced Ads 無料版だけでも発生するのか

エラーの起点はコアプラグインの abstract-group.php だが、実際に問題を引き起こしているのは Pro版のキャッシュバスティングモジュールだ。無料版のみの利用では通常発生しない。ただし同じ PHP 8.4 環境で他のアドオンを使っている場合は、類似の型エラーに注意が必要だ。

この記事のポイント

  • Advanced Ads 2.0.23 + Pro キャッシュバスティングの組み合わせで発生する
  • 管理画面にアクセスできないときは FTP でプラグインフォルダをリネームして無効化する
  • コアプラグインを 2.0.22 にロールバックすれば復旧できる
  • キャッシュバスティングの無効化は暫定対処であり根本解決にはならない
  • PHP 8.4 の厳格な型チェックがエラーの引き金になっている
ブロックエディタが点滅してクラッシュする時の原因と直し方

ブロックエディタが点滅してクラッシュする時の原因と直し方

ブロックエディタの画面が激しく点滅し、操作不能になったりエラーでクラッシュする場合、原因の大半はブラウザ拡張機能やキャッシュ、プラグイン競合による JavaScript の競合だ。セーフモードでの編集とブラウザのトラブルシューティングを順に行えば、大半のケースはすぐに編集を再開できる。

なぜブロックエディタが点滅してクラッシュするのか

なぜブロックエディタが点滅してクラッシュするのか

今回の事象の中心にあるのは getComputedStyle@[native code] から始まる JavaScript エラーだ。ブロックエディタは React ベースの画面であり、DOM 要素のスタイルを動的に計算する処理を多用している。この getComputedStyle 呼び出しが失敗すると、React の内部状態が破綻し、画面全体の再描画が無限ループに陥って「点滅」が発生する。

エラーが起きるトリガーは主に以下の3つだ。

  • AdBlock や Grammarly、翻訳ツールなど、ページの DOM 構造を書き換えるブラウザ拡張機能がエディタの動作と衝突している
  • プラグインやテーマが独自に読み込む古い JavaScript ライブラリが、WordPress 本体のバンドル済み React と二重読み込みになっている
  • ブラウザやサーバーに残ったキャッシュが、更新後のスクリプトと旧バージョンのスクリプトを混在させている

点滅はエディタが「レンダリング → クラッシュ → 再マウント → レンダリング」を一瞬で繰り返すために起こる。ユーザーからは、画面全体がチカチカしてボタンやブロックをクリックできない、またはクリックした瞬間に「このブロックでエラーが発生しました」と表示されて操作不能になる状態として見える。

Before(点滅発生中)

エディタ画面全体が高速で明滅し、ブロックを選択できない。クリックすると「このサイトで重大なエラーが発生しました」と表示される。

After(正常動作)

エディタが安定し、ブロックの選択・編集・移動が問題なく行える。画面のちらつきは完全に消えている。

エラー状態  修正後

ビジュアルエディタの点滅を止めて編集を再開する手順

ビジュアルエディタの点滅を止めて編集を再開する手順

原因を一つずつ潰していくのが確実だ。以下の手順は、影響範囲が小さくすぐ試せるものから並べている。手順1〜3で解決しなければ、手順4以降の WordPress 内部の切り分けに進む。

STEP 1 ブラウザ拡張機能をすべて無効にする
STEP 2 シークレットウィンドウで動作確認する
STEP 3 ブラウザキャッシュとサーバーキャッシュを削除する
STEP 4 プラグインの競合を切り分ける(セーフモード)
STEP 5 テーマを標準テーマに切り替える

ブラウザ拡張機能をすべて無効にして試す

最も短時間で試せて、かつ最も解決率が高い対処だ。ブロックエディタは高度な JavaScript で動作しており、広告ブロッカーや文法チェッカーなどの拡張機能が DOM に手を加えると、React の仮想 DOM と実際の DOM の整合性が崩れて getComputedStyle エラーが発生する。特に AdBlock 系、Grammarly、翻訳アドオン、ユーザースクリプト(Tampermonkey 等)が競合しやすい。

Chrome の場合、アドレスバー右の拡張機能アイコンから「拡張機能を管理」を開き、すべての拡張機能を一度オフにする。その状態でエディタを開き直し、点滅が収まるかを確認する。収まった場合は、拡張機能をひとつずつオンにして犯人を特定する。

シークレットウィンドウかゲストモードで動作を確認する

拡張機能を一括で無効化できるもっと手軽な方法が、シークレットウィンドウ(Chrome は Ctrl+Shift+N、Firefox は Ctrl+Shift+P)だ。シークレットモードでは拡張機能がデフォルトで無効になるため、ここで問題が再現しなければ、原因はほぼ確実に拡張機能かブラウザのキャッシュにある。

別のブラウザ(普段 Chrome を使っているなら Firefox や Edge)をインストールし、拡張機能を何も入れていない状態でエディタにアクセスするのも有効な切り分けになる。複数ブラウザで同じエラーが出る場合は、拡張機能ではなく WordPress 側の問題の可能性が高い。

ブラウザキャッシュとサーバーキャッシュを削除する

WordPress のバージョンアップやプラグイン更新の直後に点滅が始まった場合、ブラウザに古い JavaScript ファイルがキャッシュされている可能性が高い。キャッシュされた古いスクリプトと、サーバー上の新しいスクリプトが混ざると、関数の呼び出し不一致で React がクラッシュする。

  • ブラウザのキャッシュと Cookie を全期間で削除する(Chrome 設定→プライバシーとセキュリティ→閲覧履歴データの削除→「キャッシュされた画像とファイル」にチェック→全期間)
  • サーバー側で W3 Total Cache や WP Super Cache などのキャッシュプラグインを使っている場合は、管理画面から「全キャッシュを削除」する
  • Cloudflare などの CDN を利用している場合は、ダッシュボードでキャッシュをパージする
  • 一部のレンタルサーバーで提供される独自キャッシュ機能もオフにする

セーフモードでプラグインの競合を切り分ける

ここまでの手順で解決しない場合、WordPress 内部で JavaScript の競合が起きている。特定のプラグインやテーマが、WordPress 本体がバンドルしている React とは別バージョンの React を読み込んでいたり、jQuery の古いバージョンや別の JavaScript ライブラリを強制的に読み込んでいるケースが多い。

全プラグインを一度に無効化すると管理画面まで影響が出る操作もあるため、WordPress のトラブルシューティングモード(Health Check & Troubleshooting プラグイン)を使うのが安全だ。このプラグインをインストールして有効化すると、管理画面のツールバーに「トラブルシューティングモード」ボタンが現れる。これを押すと、自分だけに影響するセッションで、すべてのプラグインが無効化され標準テーマに切り替わった状態でエディタをテストできる。他の訪問者には通常通りのサイトが表示される。

トラブルシューティングモードでエディタが正常に動けば、原因はプラグインかテーマにある。次にプラグインをひとつずつ有効化していき、どのプラグインを有効にした瞬間に点滅が再発するかを特定する。Health Check プラグインが使えない環境では、本番に近いテスト環境(ステージング)を作って同じ手順を行う。

テーマを標準テーマに切り替える

有料テーマやカスタマイズの多いテーマは、独自のページビルダーやアニメーションライブラリを読み込んでいることがある。プラグインをすべて無効化しても直らない場合、テーマが原因の可能性が高い。一時的に Twenty Twenty-Five などの標準テーマに切り替え、エディタの点滅が止まるか確認する。

テーマを切り替えるとウィジェットやメニュー構成が変わる可能性があるため、先にサイトのバックアップを取ることを推奨する。点滅がテーマに起因していた場合は、テーマの開発元に getComputedStyle エラーの情報を添えて問い合わせるか、子テーマで競合するスクリプトの読み込みを停止させる。

点滅エラーの詳細を開発者ツールで特定する方法

点滅エラーの詳細を開発者ツールで特定する方法

どうしても原因がわからない場合や、特定のプラグインをどうしても無効化できない事情がある場合は、ブラウザの開発者ツールで詳細なエラー情報を収集する。

  • Chrome で F12 キー(開発者ツール)を開き、「Console」タブを確認する
  • 赤いエラーメッセージの右に表示される「ソース」のリンクをクリックすると、エラーが発生している JavaScript ファイルと行番号が表示される
  • ファイルパスに /wp-content/plugins/プラグイン名//wp-content/themes/テーマ名/ が含まれていれば、そのプラグインまたはテーマがエラーの発生源だ
  • 「Network」タブで、404 エラー(Not Found)になっている .js ファイルがないかも確認する。ファイルの読み込みに失敗していると、依存する React の処理が途中で止まりクラッシュする

これらの情報を、原因と思われるプラグインやテーマのサポートフォーラムに提出すれば、開発者側での修正も期待できる。エラーメッセージを丸ごとコピーして伝えるとスムーズだ。

それでも直らない時の一時的な回避策

それでも直らない時の一時的な回避策

納期が迫っていてどうしても編集を進めなければならない場合、以下の回避策で作業を継続できる。

コードエディタで直接編集する

ビジュアルエディタが使えなくても、ブロックエディタの右上の三点メニューから「コードエディタ」に切り替えれば、HTML ベースでブロックの内容を編集できる。ビジュアルのプレビューは見られないが、少なくとも点滅に悩まされずにテキストの修正やブロック構造の調整は可能だ。

クラシックエディタプラグインを一時的に有効化する

Classic Editor プラグインをインストールして有効化すると、旧来のクラシックエディタで記事を編集できる。点滅の原因がブロックエディタ固有の React 処理にある場合、クラシックエディタでは問題が発生しないことが多い。作業が完了したらプラグインを無効化して元のブロックエディタに戻し、根本原因の調査を続ける。

よくある質問

同じブラウザで他の WordPress サイトは正常に動く。自サイトだけ点滅するのはなぜか

自サイトのプラグインまたはテーマが読み込んでいる JavaScript が原因だ。他の WordPress サイトが正常なのは、そのサイトでは問題のスクリプトが読み込まれていないからだ。「セーフモードでプラグインの競合を切り分ける」手順で原因のプラグインやテーマを特定する。

getComputedStyle エラーは WordPress のバージョンを戻せば直るか

バージョンを戻すことで一時的に直るケースはあるが、セキュリティ更新が適用されなくなるため推奨しない。WordPress 本体には問題がなく、特定のプラグインやテーマが新しい WordPress のバンドル済み React に対応していないことがほとんどだ。プラグインやテーマの更新を待つか、開発元に報告して対応を依頼する方が安全だ。

ブラウザのハードウェアアクセラレーションは関係あるか

ごくまれに、GPU レンダリングの不具合が画面の点滅を引き起こすことがある。Chrome の設定→システム→「ハードウェア アクセラレーションが使用可能な場合は使用する」をオフにして再起動すると直るケースも報告されている。ただし、getComputedStyle エラーを伴う場合は JavaScript の競合が原因の可能性が高い。

全プラグイン無効化と標準テーマでも直らない場合はどうするか

ここまで試しても直らない場合は、WordPress 本体のファイル破損やサーバー側の特異な設定(mod_security など)が影響している可能性がある。WordPress の再インストール(「ダッシュボード→更新」から「再インストール」を実行)を試す。それでもダメならサーバーのエラーログを確認し、PHP のメモリ制限や実行時間制限が不足していないかも調べる。

エラーのスタックトレースにプラグイン名が出ていない時はどう調べるか

エラーが react-dom.min.jscomponents.min.js で発生している場合、直接の原因箇所がミニファイされた WordPress 本体のファイルになっている。この場合は「Network」タブで、読み込まれているすべての .js ファイルを確認する。プラグインが読み込むスクリプトの数が多い順に疑い、ひとつずつ無効化して切り分ける。

この記事のポイント

  • ブロックエディタの点滅と getComputedStyle エラーの主因はブラウザ拡張機能と JavaScript 競合
  • シークレットウィンドウと拡張機能無効化で素早く原因を絞り込める
  • Health Check プラグインのトラブルシューティングモードで安全にプラグインを切り分ける
  • どうしても急ぐ場合はコードエディタや Classic Editor プラグインで一時的に編集を続行できる
Bricks Builderのカスタムコードで同意管理プラグインが効かない時の直し方

Bricks Builderのカスタムコードで同意管理プラグインが効かない時の直し方

Kanslieri Cookie ConsentでGoogle AnalyticsやMicrosoft Clarityを自動ブロックする設定にしているのに、シークレットウィンドウで計測タグが動いてしまう原因は、Bricks Builderのカスタムコード欄に直書きしたスクリプトを、同意管理プラグインが認識できない仕組みにある。スクリプトを手動ブロック用の属性に書き換えるか、WordPress標準のエンキュー方式に差し替えれば、同意前の計測を確実に止められる。

なぜBricksカスタムコードの計測タグがブロックされないのか

なぜBricksカスタムコードの計測タグがブロックされないのか

Kanslieri Cookie Consentをはじめ、多くのCookie同意管理プラグインは、WordPressの標準機能であるwp_enqueue_scriptで読み込まれたスクリプトをフックして制御する設計になっている。スクリプトのハンドル名を解析し、同意が得られるまで実行を自動的に保留する仕組みだ。

一方、Bricks Builderの「Settings → Custom Code → Header Scripts」に貼り付けたコードは、テーマがwp_headアクションを通じてページのソースにそのまま埋め込む。プラグイン側からは「PHPで読み込まれたスクリプト」として認識されず、単なるインラインHTML扱いになる。その結果、管理画面のScript Blockingページに「Google Analyticsは自動ブロック対象」と表示されていても、実際にはブロックが効かない。

Google Analyticsの_ga_gidといったCookieがシークレットウィンドウで生成され、/g/collectへのリクエストが送信され、page_viewscrollイベントが記録されるのはこのためだ。Microsoft Clarityも同様に、カスタムコード欄経由では自動ブロックの対象外になる。

同意前のトラッキングを防ぐ具体的な修正手順

同意前のトラッキングを防ぐ具体的な修正手順

Kanslieri Cookie Consentの自動ブロックが効かない場合でも、手動ブロックの仕組みを利用すれば計測を止められる。修正方法は大きく2つある。すでにカスタムコードを使っているなら、スクリプトタグに手動ブロック用の属性を追加するのが最も手早い。

手動ブロック用のtype属性に書き換える方法

Kanslieri Cookie Consentは、スクリプトタグのtype属性をtext/plainに書き換えることで、同意があるまでスクリプトの実行を止める仕組みを持っている。同意が得られた時点で、プラグインがtypetext/javascriptに戻して実行する。Bricksのカスタムコード欄に貼ってあるGoogle AnalyticsとMicrosoft Clarityのコードを、次のように修正する。

修正前
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>
修正後
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX" type="text/plain" data-cookiecategory="analytics"></script>
<script type="text/plain" data-cookiecategory="analytics">
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>
修正前(自動ブロック非対応)  修正後(手動ブロック対応)

ポイントは各<script>タグにtype="text/plain"data-cookiecategory="analytics"を追加することだ。data-cookiecategoryの値は、Kanslieri Cookie Consentの設定で該当スクリプトを割り当てたいカテゴリ名と一致させる。Google Analyticsならanalytics、Microsoft Clarityも同じ分析カテゴリで構わない。複数カテゴリにまたがる場合はdata-cookiecategory="analytics, marketing"のようにカンマ区切りで指定できる。

WordPressのエンキュー方式に切り替える方法

より根本的な解決策として、カスタムコード欄ではなく子テーマのfunctions.phpからwp_enqueue_scriptでスクリプトを読み込む方法もある。この方法なら、Kanslieri Cookie Consentの自動ブロック機能が確実に働く。

function my_google_analytics_script() {
    wp_enqueue_script(
        'google-analytics',
        'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX',
        array(),
        null,
        false
    );
    wp_add_inline_script(
        'google-analytics',
        "window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'G-XXXXXXXXXX');"
    );
}
add_action('wp_enqueue_scripts', 'my_google_analytics_script');

このコードを子テーマのfunctions.phpに追加したら、Bricksのカスタムコード欄から該当のコードを削除する。Kanslieri Cookie ConsentのScript BlockingページでGoogle Analyticsが認識されるようになり、同意前のトラッキングが自動的にブロックされる。

手動ブロックが正しく動くか確認する手順

手動ブロックが正しく動くか確認する手順
STEP 1 ブラウザのシークレットウィンドウを開く(Cookieが初期化された状態)
STEP 2 サイトにアクセスし、Cookie同意バナーが表示されたら同意せずに待つ
STEP 3 Chrome DevToolsの「Application → Cookies」で_gaや_gidが生成されていないことを確認
STEP 4 「Network」タブでgoogle-analytics.comやclarity.msへのリクエストが発生していないことを確認

DevToolsのNetworkタブでは、フィルタにcollectclarityと入力すると該当リクエストを素早く見つけられる。同意前にこれらのリクエストが記録されていなければ、ブロックは正しく機能している。その状態でCookieバナーの「同意する」をクリックし、直後にリクエストが走り始めれば、同意後の計測も正常に動作していることになる。

Bricks Builderのキャッシュが有効になっている場合は、修正後にかならずキャッシュをクリアする。Bricksの管理画面から「Bricks → Settings → Performance」でキャッシュを削除したうえで、サーバー側のキャッシュやCDNがある場合も同時にパージする。キャッシュが残っていると修正前のスクリプトが配信され続けてしまうため、確認作業の前に忘れずに行う必要がある。

よくある質問

他のページビルダー(ElementorやDivi)でも同じ問題は起きるのか

起きる可能性が高い。Elementorのカスタムコード機能やDiviの統合設定から追加したスクリプトも、テーマ側で直接HTMLに出力されるため、同意管理プラグインの自動ブロック対象外になりやすい。同じ手動ブロックの手法が適用できる。ただし、Elementorの場合はwp_enqueue_script方式に切り替える方が推奨される場面が多い。カスタムコード欄にスクリプトを置く運用は、同意管理の観点からは避けるのが無難だ。

Kanslieri Cookie Consentの自動ブロックが効かないスクリプトを見分ける方法はあるか

管理画面の「Script Blocking」ページに一覧表示されるスクリプトは、プラグインが自動検出できたものだけだ。ここに表示されていないGoogle AnalyticsやClarityのスクリプトは自動ブロック対象外と判断してよい。また、シークレットウィンドウで実際にCookieが生成されるか、DevToolsでネットワークリクエストが発生するかを確認すれば、ブロックの可否を実動作で検証できる。

手動ブロックに書き換えたスクリプトが、同意後も動かない場合はどうするのか

Kanslieri Cookie Consentの設定で、data-cookiecategoryに指定したカテゴリが有効になっているか確認する。「Cookie Settings」画面で該当カテゴリのトグルがオンになっていること、同意バナーでユーザーがそのカテゴリを許可できる選択肢が表示されていることをチェックする。カテゴリ名にタイプミスがあると、プラグインがスクリプトをどのカテゴリに紐づけてよいか判断できず、同意後も実行されない。

Bricksのカスタムコードは使わず、Google Site KitプラグインでGA4を入れるとどうなるか

Site Kitはwp_enqueue_scriptを使ってGoogle Analyticsタグを読み込むため、Kanslieri Cookie Consentの自動ブロック機能が正常に働く。手動ブロックの書き換えは不要になる。すでにカスタムコードでGA4を入れている場合は、そのコードを削除してSite Kitに移行するだけで、同意管理の課題が解決する。Clarityも公式プラグインを使えば同様だ。

この記事のポイント

  • Bricks Builderのカスタムコード欄は同意管理プラグインの自動ブロック対象外になる
  • スクリプトタグにtype="text/plain"とdata-cookiecategoryを追加して手動ブロックに対応させる
  • wp_enqueue_scriptで読み込めば自動ブロックが有効になり修正不要
  • 修正後はシークレットウィンドウとDevToolsでCookieとリクエストを検証する
  • キャッシュクリアを忘れると修正が反映されない
WooCommerce HPOSが48時間で100万件以上のアクションスケジューラ完了ジョブを生成した原因と対処法

WooCommerce HPOSが48時間で100万件以上のアクションスケジューラ完了ジョブを生成した原因と対処法

WooCommerceサイトでデータベースサイズが突然急増し、wp_actionscheduler_actionsテーブルに数百万件もの完了済みジョブが蓄積している場合、HPOSデータ同期バッチプロセスが無限ループを起こしている可能性が極めて高い。ここでは症状の見分け方から原因の特定、停止、クリーンアップまで、具体的な手順をまとめる。

HPOS関連のデータベース肥大化が疑われる症状

HPOS関連のデータベース肥大化が疑われる症状

以下のような兆候が複数同時に現れたら、Action Schedulerの暴走を疑ってよい。

  • データベース容量が短時間で急激に増加する(数GB単位)
  • PHPエラーログのファイルサイズが異常に大きくなる
  • データベースのロックエラーやデッドロックが頻発する
  • 管理画面やフロントエンドで「INSERT command denied」などのエラーが出る
  • サーバーのバックグラウンドプロセスがほぼ常時稼働し続ける
  • 注文件数が数百件なのにAction Schedulerテーブルだけが肥大化している

これらの症状は、単体では他の原因もあり得るが、データベース内の完了ジョブが異常に増えている点が最大の特徴だ。

正常時(Before)
wp_actionscheduler_actions テーブルに数百件程度のジョブが存在する
暴走時(After)
100万件以上の完了ジョブが蓄積し、データベース全体が膨張する
正常時  暴走時

Action Schedulerが暴走していないか確認する方法

Action Schedulerが暴走していないか確認する方法

まずはデータベースを直接調べ、どのジョブが何件蓄積しているかを確かめる。WP-CLIが使えるならコマンドラインから、そうでなければphpMyAdminやAdminerで以下のクエリを実行する。

STEP 1 Action Schedulerテーブルの完了ジョブ数を集計する
STEP 2 フック名「wc_run_batch_process」でフィルタし、引数を確認する
STEP 3 注文件数とジョブ件数を比較し、異常な乖離を確認する
STEP 4 実行中のジョブが1件完了するたびに次が即座にスケジュールされるループを特定する

完了ジョブの数とフック名を調べる

データベースに直接問い合わせる場合、以下のSQLで完了状態のジョブをフック名別に集計できる。

SELECT hook, COUNT(*) AS cnt
FROM wp_actionscheduler_actions
WHERE status = 'complete'
GROUP BY hook
ORDER BY cnt DESC
LIMIT 10;

ここで wc_run_batch_process の件数が数十万〜数百万件と突出していれば、疑いは濃厚だ。

引数(args)から発行元を特定する

次に、そのフックの引数を見る。例えば以下のクエリで先頭の数件を取得する。

SELECT action_id, args, scheduled_date_gmt
FROM wp_actionscheduler_actions
WHERE hook = 'wc_run_batch_process'
AND status = 'complete'
ORDER BY action_id DESC
LIMIT 5;

引数フィールドにはシリアライズされたデータが入っている。その中に Automattic\WooCommerce\Internal\DataStores\Orders\DataSynchronizer という文字列が含まれていれば、HPOSのデータ同期機構がバッチを発行している証拠だ。

注文件数との比較で異常を確信する

管理画面のWooCommerce → 注文で表示される注文の総数は、データベースの wp_posts(またはHPOS有効時は wp_wc_orders)で確認できる。注文が600件しかないのに、同期バッチの完了ジョブが100万件もあるなら、明らかにループが発生している。

動作中のループをリアルタイムで観察する

WP-CLIが利用可能なら、以下のコマンドでペンディング状態のジョブを監視する。

wp action-scheduler list --hook=wc_run_batch_process --status=pending

定期的に実行すると、常に1件だけ存在し、それが完了するとすぐに新たなペンディングが生まれるパターンが観測できるはずだ。これはキューが滞留しているのではなく、バッチ自身が次をスケジュールし続ける無限ループであることを示す。

なぜHPOS DataSynchronizerが無限ループを起こすのか

なぜHPOS DataSynchronizerが無限ループを起こすのか

HPOS(High-Performance Order Storage)を有効にすると、WooCommerceは注文データを従来の wp_posts テーブルから専用テーブルへ移行する。この移行やデータの同期を担うのが DataSynchronizer であり、バックグラウンドでバッチ処理を走らせる。

通常は同期が完了すればバッチは停止するが、何らかの設定不整合やエラーにより「同期が完了したと見なされず、次のバッチが即座に予約される」状態に陥ることがある。具体的には、各バッチが「保留中 → 完了 → 次バッチ予約」というサイクルを際限なく繰り返す。注文数が少なくても、このループによってAction Schedulerのテーブルだけが急激に肥大化し、データベース全体を圧迫する。

保留中(Pending)
完了(Complete)
次バッチ予約(Schedule Next)
再び 保留中(Pending)へ
↑ 無限にループする

このループが起きているかどうかは、データベースを直接見るまで気づきにくい。キャッシュやRedis、WP Rocketなどを最初に疑いがちだが、真因はAction Schedulerの中にある。

データベースの安静化とクリーンアップの手順

データベースの安静化とクリーンアップの手順

原因がHPOSの同期バッチループと判明したら、ループを止め、完了ジョブを削除し、再発を防ぐ。以下の手順を順に実行する。

STEP 1 WP-CLIで同期状態を確認し、必要に応じて同期をリセットする
STEP 2 Action Schedulerの完了ジョブを安全に一括削除する
STEP 3 データベーステーブルを最適化し、容量を解放する
STEP 4 再発防止のためにHPOS設定を見直す

同期状態のリセット

まず、現在のHPOS同期状況を確認する。WP-CLIで次のコマンドを実行する。

wp wc hpos sync status

ここで「status: in-progress」や「pending」が表示される場合、同期が完了しておらず、バッチが動き続けている可能性がある。強制的にリセットし、不要な同期を停止するには以下を実行する。

wp wc hpos sync reset

リセット後、再度ステータスを確認し「idle」や「complete」になっていれば、新たなバッチはスケジュールされなくなる。

完了ジョブの一括削除

100万件単位の完了ジョブを削除するには、Action Schedulerが提供するWP-CLIコマンドを使うのが安全で高速だ。以下のコマンドで、完了状態のジョブをすべて削除できる。

wp action-scheduler clean --status=complete

特定のフックのみを削除したい場合は、プレーンなSQLで一度に削除してもよいが、必ず事前にデータベース全体のバックアップを取ること。

DELETE FROM wp_actionscheduler_actions
WHERE hook = 'wc_run_batch_process' AND status = 'complete';

さらに、関連するログテーブル(wp_actionscheduler_logs)の不要レコードも合わせて削除すると、ディスク容量を大きく回復できる。ただし、こちらは慎重に扱う必要があるため、まずは完了ジョブの削除だけでも効果は大きい。

テーブル最適化で容量を解放

大量のレコードを削除した後は、データベースが断片化し、実際の容量が解放されないことがある。phpMyAdminなどから該当テーブルに対して「最適化(OPTIMIZE TABLE)」を実行するか、以下のSQLを流す。

OPTIMIZE TABLE wp_actionscheduler_actions;
OPTIMIZE TABLE wp_actionscheduler_logs;

これにより、削除した領域がOSに返却され、データベース全体のサイズが縮小する。

再発防止とHPOS設定の見直し

ループが再発しないように、WooCommerceのHPOS設定を確認する。管理画面の WooCommerce → 設定 → 詳細設定 → 機能 から「High-performance order storage(高性能注文ストレージ)」が有効になっているか、そして「互換モードを有効にする」や「データ同期を有効にする」オプションがどのようになっているかをチェックする。

既に全注文がHPOSテーブルに完全移行済みで、互換モードが不要なら、これらの同期オプションを無効化することで、バックグラウンドのバッチ処理そのものを止められる。ただし、テーマやプラグインが古い注文データ参照方法を使っている場合は注意が必要だ。

また、WP-CLIのcronを定期的に監視し、Action Schedulerのジョブ数が異常増加していないかをチェックする仕組みをサーバー監視に組み込むと早期発見につながる。

よくある質問

HPOSが有効かどうかはどこで確認できるか

管理画面の「WooCommerce → 設定 → 詳細設定 → 機能」に移動し、「注文データストレージ」の項目で「High-performance order storage」が選択されていれば有効だ。WP-CLIでは wp wc hpos status で確認できる。

完了ジョブを削除してもサイト動作に影響はないか

Action Schedulerの完了ジョブは過去の処理履歴であり、削除しても現在予約されているジョブや進行中の処理には影響しない。ただし、監査やデバッグ目的で残したい場合は、削除前にバックアップを取ることを強く推奨する。

WP-CLIが使えないレンタルサーバーではどうすればよいか

phpMyAdminなどのデータベース管理ツールから直接SQLで削除できる。プラグイン「WP Crontrol」などを利用すれば、Action Schedulerの一覧を管理画面で確認し、フックごとに手動で削除することも可能だが、件数が多い場合はSQLのほうが現実的だ。

同期をリセットしてもループが再発するのはなぜか

根本原因が解消されていないと再発する。たとえば、同期オプションが有効なまま残っていたり、カスタムコードがバッチをトリガーし続けているケースがある。同期の完全停止を試み、プラグインの干渉も疑いながら一つずつ切り分ける必要がある。

この記事のポイント

  • データベースの急激な肥大化とAction Schedulerの完了ジョブ数に注目する
  • フック名「wc_run_batch_process」と引数からHPOSの同期バッチループを特定する
  • WP-CLIで同期状態をリセットし、完了ジョブを一括削除してテーブルを最適化する
  • HPOSの同期設定を見直し、不要なバッチ処理を完全に止めて再発を防ぐ
WordPressで重大なエラーが発生した時の原因と復旧手順

WordPressで重大なエラーが発生した時の原因と復旧手順

WordPressで「このサイトで重大なエラーが発生しました」と表示され管理画面にもログインできない場合、まず試すべきはサーバーのエラーログ確認と、FTPを使った原因プラグインの強制停止だ。管理用メールが届かなくても、手動の切り分け作業でサイトを復旧できる。

なぜ「このサイトで重大なエラーが発生しました」と表示されログイン不能になるのか

なぜ「このサイトで重大なエラーが発生しました」と表示されログイン不能になるのか

あのメッセージが表示されるとき、WordPress内部ではPHPの「致命的エラー(Fatal Error)」が起きている。プログラムの処理がそこで停止してしまい、画面表示が途中で終わる。テーマやプラグインの更新失敗、PHPバージョンの非互換、サーバーのメモリ上限超過、あるいはコアファイルの破損など原因は多岐にわたる。

WordPress 5.2以降、致命的エラーが起きると管理画面へのログインも止められる設計になった。これは「壊れかけのサイトを操作し続けて被害を拡大させない」ための安全措置だ。通常なら「サイトに技術的な問題が発生しました。復旧手順のリンクを管理者メールアドレスに送信しました」という案内とともに「回復モード」用のリンクがメールで届く仕組みになっている。

ただ、このメールが届かないケースは実際には非常に多い。メールサーバーの設定不備や、そもそも通知を受け取る管理者アドレスが存在しないサイトもある。つまり「メールが届かない=打つ手がない」わけではない。手動での復旧手順を覚えておけば、すぐに対処できる。

管理用メールが届かなくてもエラーの原因を特定する手順

管理用メールが届かなくてもエラーの原因を特定する手順

原因を特定できないまま闇雲に操作すると、状況をさらに悪化させかねない。まずは「一体どのファイルの何行目で止まっているのか」という技術情報を掴む必要がある。

サーバーのエラーログを最優先で確認する

「重大なエラー」の原因は、ほとんどの場合サーバー上の「エラーログ」に明瞭に記録されている。エックスサーバー、ConoHa WING、さくらのレンタルサーバなど国内の主要レンタルサーバーなら、コントロールパネル内の「エラーログ」や「アクセスログ」といったメニューから確認可能だ。cPanel系であれば「Errors」アイコンから辿れる。

  • ログには「PHP Fatal error」という文言と、問題が起きたファイルのパス(/home/…/plugins/xxxx/xxxx.php on line 123 など)が刻まれている
  • ここでプラグイン名が明記されていれば原因はほぼ特定できたも同然だ
  • もしログの見方が分からない場合は、「エラーログをダウンロードして全文をテキストエディタで開き、Fatal で検索する」とよい

wp-config.php で WP_DEBUG を有効にしてエラーを画面表示させる

エラーログがすぐに見つからない・もしくはより直感的に原因を掴みたい場合は、WordPressのデバッグモードを有効にする。FTPソフト(FileZillaなど)か、サーバーのファイルマネージャーで WordPress インストールディレクトリ直下の wp-config.php ファイルに以下の行を追加する。

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

この設定でエラー情報は /wp-content/debug.log に書き出される。ブラウザ上でサイトを再読込し、その後このログファイルを開けば、先ほどと同じように原因ファイルを特定できる。WP_DEBUG_DISPLAYtrue にすると画面に直接エラーが表示されるが、一般の訪問者にも見えてしまうので本番環境での使用は推奨しない。問題を解決したあとは false に戻すか、行ごと削除すること。

FTPやファイルマネージャーで原因のプラグインやテーマを強制停止する

FTPやファイルマネージャーで原因のプラグインやテーマを強制停止する

原因が特定のプラグインやテーマだと判明したら、管理画面に戻らなくても手動で無効化できる。管理画面を経由せず、ファイル名の変更で読み込ませないようにする手法だ。これでサイトの表示や管理画面へのアクセスが復活する。

STEP 1 サーバーのエラーログを確認する
STEP 2 wp-config.php に WP_DEBUG 設定を追記する
STEP 3 エラーメッセージから原因プラグインを特定する
STEP 4 該当プラグインをリネームして無効化する

原因プラグインのフォルダをリネームする

FTPソフトまたはレンタルサーバーのファイルマネージャーで、WordPress のインストール先に移動し、/wp-content/plugins/ ディレクトリを開く。エラーログに書かれていたプラグイン名と一致するフォルダを見つけて、名前を変更する。末尾に「_deactivated」や「_bk」などを付け足せばよい。

  • 変更前: problem-plugin
  • 変更後: problem-plugin_deactivated

WordPress はフォルダ名が一致しないプラグインを読み込まなくなる。結果、致命的エラーの原因が取り除かれ、サイトは無事に表示されるようになる。管理画面にも再びログイン可能になる。

すべてのプラグインを一括で疑う場合の方法

エラーログ上でプラグイン名が特定できないが、何らかのプラグインが原因であることは間違いない場合、/wp-content/plugins/ フォルダそのものをリネームしてしまう手もある。たとえば pluginsplugins_stop に変更すれば、すべてのプラグインが一括で無効化される。その状態で管理画面にログインできれば、原因はやはりプラグインなので、フォルダ名を元に戻し、管理画面から一つずつ有効化していく。テーマが原因と疑われる場合は、/wp-content/themes/ 以下の現在のテーマフォルダをリネームする。WordPress はテーマが存在しないとデフォルトテーマ(Twenty Twenty-Five など)に自動で切り替わる。

復旧後に必ずやっておくべき再発防止策

復旧後に必ずやっておくべき再発防止策

サイトが無事に表示され管理画面にも入れたら、そのまま運用を再開するのではなく、必ず以下の3つをチェックする。これで同じエラーが二度と起きにくくなる。

WordPress本体、テーマ、プラグインをすべて最新にする

致命的エラーは「古いソフトウェア」と「最新のPHPバージョン」の組み合わせで起きやすい。更新が止まっている長期放置プラグインが混ざっているなら、代替のメンテナンスされているプラグインへの移行を検討する。

PHPバージョンをサーバー管理画面で上げる

WordPress の推奨する PHP バージョンは常に上がっている。サーバーのコントロールパネルで PHP 8.1 以上に設定変更できるか確認する。変更後はサイト全体の動作確認を必ず行う。

WP_DEBUG の設定を本番環境で必ず解除する

wp-config.php にデバッグ設定を追加していた場合、必ず define( 'WP_DEBUG', false ); に戻すか、該当行を削除する。ログ出力を有効にしたまま運用すると、サーバーのディスク容量を圧迫し、別のトラブルを引き起こす。

よくある質問

管理画面の「回復モード」リンクがメールで届かない理由は

主な原因はサイトのメール送信機能そのものが正常に動いていないことだ。特に共用サーバーでは PHP の mail() 関数が制限されているか、WordPress の送信メールが迷惑メールフォルダに分類されている。SMTPプラグインなどで送信経路を信頼性の高いものに変えれば、次回以降の通知は確実に届くようになる。

WordPressログイン画面自体が表示されない場合の対処法は

管理画面へのアクセスすら致命的エラーで遮断されているという状態だ。まず前述の FTP を使ったプラグイン一括停止を試す。それでも改善しないなら、.htaccess ファイルの破損も疑って、ファイル名を .htaccess_bk に変更し、WordPress 管理画面の「設定」→「パーマリンク」で再生成させる。

FTPパスワードがわからないが復旧できるか

レンタルサーバーのコントロールパネルにログインできれば、多くの場合ブラウザ上で操作できる「ファイルマネージャー」が利用可能だ。FTPアカウントの情報が不明でも、ファイルマネージャーさえ使えれば全く同じ手順でプラグインフォルダのリネームができる。

すべてのプラグインを停止してもエラーが消えない

テーマが原因の可能性が高い。FTPで /wp-content/themes/ 以下の現在のテーマフォルダをリネームする。また、WordPress のコアファイルが破損していることもある。「ダッシュボード」→「更新」から WordPress の「再インストール」を実行すれば、コアファイルが上書き修復される。

WP_DEBUG を設定したが debug.log に何も記録されない

サーバー側で PHP エラーログの出力先が別に固定されているケースだ。その場合、レンタルサーバーのコントロールパネルに用意されている「エラーログ」機能に、より詳細な情報が出ている。そこを確認すれば解決の糸口がつかみやすい。また、wp-config.php の記述場所が /* That's all, stop editing! */ より上にあるかも確認する。

この記事のポイント

  • 「重大なエラー」はPHPの致命的エラーが原因で起こる
  • メールが届かなくてもサーバーのエラーログで原因を特定できる
  • FTPやファイルマネージャーでプラグインフォルダをリネームして停止する
  • 復旧後はPHPバージョンの確認とWP_DEBUGの解除が必須