「OpenClaw ブラウザ投稿フロー障害の振り返り:fields are required から stale ref までのシステムレベル修復」

OpenClaw ブラウザ投稿フロー障害ふりかえり:fields are required から stale ref までのシステムレベル修復

この記事は、実際の本番障害対応を完全にふりかえった記録であり、「なぜ壊れたのか、なぜ以前は問題なかったのか、今回具体的に何を変えたのか」を明確にし、再現可能な修復手順を提示することを目的としています。

対象読者:

  • OpenClaw で browser ツールを使って自動投稿/自動入力をしている人
  • fields are requiredElement \"eXX\" not found or not visibleNo tool call found for function call output ... に遭遇したことがある人
  • 一度きりの「応急処置」を「安定して再利用できる修復策」に昇格させたい人

一、現象と業務影響

1) 主なエラー

今回の障害では、典型的なエラーが3種類発生しました:

  1. fields are required
  2. Element \"e92\" not found or not visible. Run a new snapshot to see current page elements.
  3. 400 No tool call found for function call output with call_id ...

2) 業務上の見え方

  • ページは開ける
  • DOM は snapshot できる
  • act/fill またはノード入力アクションに入ると、browser 制御サービスがエラーで中断する
  • クロスサイト投稿フロー(Linux.do / V2EX / 2libra / iSharkFly)が連続実行できない

この種の障害は「アカウント権限問題」や「コンテキストが長すぎる」と誤判定されやすいですが、今回はそうではないことが確認できました。


二、タイムライン(重要ポイント)

  • 2026-02-23 12:44(CST)ごろ:ローカルの OpenClaw を 2026.2.22-2 にインストール/更新
  • 以後、browser の大量エラー:fields are required
  • さらに進めると stale ref:Element \"e92\" not found or not visible
  • 過去のセッションに存在:No tool call found for function call output ...
  • 最終的に、プロトコル互換 + stale ref のフォールバック修復で投稿成功を回復

補足:

  • No tool call found ...fields are required は同一問題ではありません。
  • コンテキストウィンドウを下げる(例:1048576 → 200000)だけでは、この2つの根本エラーは直接解消できません。

三、原因分解

原因 A:fill プロトコル非互換(最初に爆発)

上流のアクションリクエストでよくある形は:

{
  "kind": "fill",
  "ref": "e57",
  "text": "..."
}

しかし現在のルーティング実装は、より次の形を要求する傾向があります:

{
  "kind": "fill",
  "fields": [
    { "ref": "e57", "type": "text", "value": "..." }
  ]
}

fields が提供されず互換マッピングもない場合、即座に fields are required が発火します。

原因 B:動的ページにより ref がドリフト(stale ref)

例:

  • snapshot 時に e92 を取得
  • コンポーネント再描画/モーダル切替後に e92 が無効化
  • 後続の type/fill が古い ref のまま実行され、not found or not visible が発生

これは V2EX のノード選択入力欄など、動的 UI で非常に起きやすい現象です。

原因 C:No tool call found ... はセッション呼び出し状態の不整合

このエラーは session/tool-call の経路不一致(call_id が一致しない)であり、ブラウザ DOM 操作失敗そのものではありません。


四、修復目標と戦略

目標は「一点パッチ」ではなく、投稿フローを「互換 + 自己回復 + 可観測」にすることです:

  1. 旧リクエスト形を互換し、fields are required を回避
  2. stale ref を自動回復し、毎回手動で snapshot を取り直さなくてよいようにする
  3. 2回目の失敗でもフォールバックし、重要な書き込みポイントでフローが即死しないようにする

五、実際の変更点(実行時 dist)

補足:OpenClaw はビルド後に複数の hash 生成物が存在するため、重要な分岐は同期して埋めないと、実行時に未修正の bundle を踏む可能性があります。

1) fill 互換レイヤー

/actcase \"fill\" に互換マッピングを追加:

  • fields が欠落している場合、{ref,text/value}fields:[{ref,type:\"text\",value}] に自動変換
  • field の type のデフォルト値として text を提供

2) stale ref の自動リトライ

case \"type\"case \"fill\" にて:

  • Unknown ref / not found or not visible を捕捉
  • snapshotRoleViaPlaywright({ refsMode: \"aria\" }) を1回自動実行
  • その後、元のアクションを再試行

3) 第2層フォールバック(今回の重要強化)

「snapshot 取り直し + 再試行」後も stale ref で失敗する場合:

  • typedocument.activeElement に直接値を書き込み、input/change を dispatch
  • fill:単一フィールドのテキストケースでも同様に activeElement 書き込みでフォールバック

これにより「フォーカスは目的の入力欄に残っているが、古い ref が失効している」という高頻度ケースをカバーできます。

4) 対象ファイル

  • /opt/homebrew/lib/node_modules/openclaw/dist/routes-CmNAokG-.js
  • /opt/homebrew/lib/node_modules/openclaw/dist/routes-FGJF5gtZ.js
  • /opt/homebrew/lib/node_modules/openclaw/dist/pi-embedded-helpers-CNhhELVT.js
  • /opt/homebrew/lib/node_modules/openclaw/dist/pi-embedded-helpers-DxTyisc4.js

六、検証手順(再現可能)

  1. gateway を再起動し、新プロセスが有効であることを確認(PID が変わる)
  2. 同一路径の自動投稿フローを実行
  3. ログに以下が引き続き出ていないか確認:
    • fields are required
    • Element \"eXX\" not found or not visible
  4. 業務結果を検証:投稿が実際に作成成功しているか

今回の結果:

  • 障害パスは復旧し、投稿成功。

七、なぜ「一昨日は正常で、今回はこんなに直す必要があった」のか?

結論は明確です:

  1. バージョン変化がプロトコル差分を増幅した

    • ローカルの現在バージョン:[email protected]
    • このバージョンでは fill 入口が fields[] 形に対してより厳格
  2. 同じ問題を複数の dist 入口で埋める必要があった

    • 「多くのファイルを直したように見える」が、本質は「同一ロジックが複数のバンドル生成物に重複して存在」しているため
  3. 動的ページの ref ドリフトは構造的リスク

    • 以前ぶつからなかっただけで、存在しないわけではない
    • 再描画頻度が上がると集中的に噴出する

従って今回は「単なる設定問題」ではなく、「プロトコル互換 + 動的 UI 安定性」の同時欠落でした。


八、今後の提案(リグレッション防止)

1) プロトコル層の提案

  • browser action プロトコルで fill の canonical schema を明文化
  • 旧 schema について後方互換ウィンドウを維持し、ログで移行を促す

2) 実行層の提案

  • type/fill/click に対し、設定可能な「自動 snapshot 前置」スイッチ(高安定モード)を追加
  • stale-ref リトライ分岐に構造化ログを入れる(フォールバックが発火したか確認しやすい)

3) 運用層の提案

  • アップグレードごとに最小 E2E を実行:open → snapshot → fill → submit
  • 重要エラー(fields are requiredUnknown ref)をアラートに接続

4) セッション層の提案

  • No tool call found ... は別途調査(セッション完全性/リプレイ整合性)し、browser DOM 問題と混ぜて切り分けない

九、障害対応チェックリスト(未来の自分へ)

同様の問題に遭遇したら、この順で進める:

  1. まずエラー種別を分離(プロトコル/DOM/session)
  2. 最新ログの時刻を確認し、古いエラーで誤判定しない
  3. リクエスト payload の形が現行バージョンに合っているか検証
  4. stale ref に「snapshot リトライ + activeElement フォールバック」を追加
  5. 再起動し、新プロセスが新コードをロードしていることを確認
  6. 同パスで再テストし、エラーが消えただけでなく業務成功していることを確認

十、結び

今回の修復は「エラーを隠す」ことではなく、投稿フローを3層のレジリエンスで補強しました:

  • 第1層:プロトコル互換(構造不一致を防ぐ)
  • 第2層:自動回復(snapshot 後のリトライ)
  • 第3層:入力フォールバック(activeElement 書き込み)

最終目標はただ一つ:実際の動的 Web ページ上で、自動化フローを持続可能・再現可能・保守可能にすること。

OpenClaw のブラウザ自動化をしているなら、この3層戦略をデフォルトテンプレートとして固定化することをおすすめします。