OpenClaw ブラウザ投稿フロー障害ふりかえり:fields are required から stale ref までのシステムレベル修復
この記事は、実際の本番障害対応を完全にふりかえった記録であり、「なぜ壊れたのか、なぜ以前は問題なかったのか、今回具体的に何を変えたのか」を明確にし、再現可能な修復手順を提示することを目的としています。
対象読者:
- OpenClaw で browser ツールを使って自動投稿/自動入力をしている人
fields are required、Element \"eXX\" not found or not visible、No tool call found for function call output ...に遭遇したことがある人- 一度きりの「応急処置」を「安定して再利用できる修復策」に昇格させたい人
一、現象と業務影響
1) 主なエラー
今回の障害では、典型的なエラーが3種類発生しました:
fields are requiredElement \"e92\" not found or not visible. Run a new snapshot to see current page elements.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 操作失敗そのものではありません。
四、修復目標と戦略
目標は「一点パッチ」ではなく、投稿フローを「互換 + 自己回復 + 可観測」にすることです:
- 旧リクエスト形を互換し、
fields are requiredを回避 - stale ref を自動回復し、毎回手動で snapshot を取り直さなくてよいようにする
- 2回目の失敗でもフォールバックし、重要な書き込みポイントでフローが即死しないようにする
五、実際の変更点(実行時 dist)
補足:OpenClaw はビルド後に複数の hash 生成物が存在するため、重要な分岐は同期して埋めないと、実行時に未修正の bundle を踏む可能性があります。
1) fill 互換レイヤー
/act の case \"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 で失敗する場合:
type:document.activeElementに直接値を書き込み、input/changeを dispatchfill:単一フィールドのテキストケースでも同様に 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
六、検証手順(再現可能)
- gateway を再起動し、新プロセスが有効であることを確認(PID が変わる)
- 同一路径の自動投稿フローを実行
- ログに以下が引き続き出ていないか確認:
fields are requiredElement \"eXX\" not found or not visible
- 業務結果を検証:投稿が実際に作成成功しているか
今回の結果:
- 障害パスは復旧し、投稿成功。
七、なぜ「一昨日は正常で、今回はこんなに直す必要があった」のか?
結論は明確です:
-
バージョン変化がプロトコル差分を増幅した
- ローカルの現在バージョン:
[email protected] - このバージョンでは
fill入口がfields[]形に対してより厳格
- ローカルの現在バージョン:
-
同じ問題を複数の dist 入口で埋める必要があった
- 「多くのファイルを直したように見える」が、本質は「同一ロジックが複数のバンドル生成物に重複して存在」しているため
-
動的ページの ref ドリフトは構造的リスク
- 以前ぶつからなかっただけで、存在しないわけではない
- 再描画頻度が上がると集中的に噴出する
従って今回は「単なる設定問題」ではなく、「プロトコル互換 + 動的 UI 安定性」の同時欠落でした。
八、今後の提案(リグレッション防止)
1) プロトコル層の提案
- browser action プロトコルで
fillの canonical schema を明文化 - 旧 schema について後方互換ウィンドウを維持し、ログで移行を促す
2) 実行層の提案
type/fill/clickに対し、設定可能な「自動 snapshot 前置」スイッチ(高安定モード)を追加- stale-ref リトライ分岐に構造化ログを入れる(フォールバックが発火したか確認しやすい)
3) 運用層の提案
- アップグレードごとに最小 E2E を実行:open → snapshot → fill → submit
- 重要エラー(
fields are required、Unknown ref)をアラートに接続
4) セッション層の提案
No tool call found ...は別途調査(セッション完全性/リプレイ整合性)し、browser DOM 問題と混ぜて切り分けない
九、障害対応チェックリスト(未来の自分へ)
同様の問題に遭遇したら、この順で進める:
- まずエラー種別を分離(プロトコル/DOM/session)
- 最新ログの時刻を確認し、古いエラーで誤判定しない
- リクエスト payload の形が現行バージョンに合っているか検証
- stale ref に「snapshot リトライ + activeElement フォールバック」を追加
- 再起動し、新プロセスが新コードをロードしていることを確認
- 同パスで再テストし、エラーが消えただけでなく業務成功していることを確認
十、結び
今回の修復は「エラーを隠す」ことではなく、投稿フローを3層のレジリエンスで補強しました:
- 第1層:プロトコル互換(構造不一致を防ぐ)
- 第2層:自動回復(snapshot 後のリトライ)
- 第3層:入力フォールバック(activeElement 書き込み)
最終目標はただ一つ:実際の動的 Web ページ上で、自動化フローを持続可能・再現可能・保守可能にすること。
OpenClaw のブラウザ自動化をしているなら、この3層戦略をデフォルトテンプレートとして固定化することをおすすめします。