OpenClawの切り分け
OpenClawを、Mac miniの上でコンテナに入れて常駐させている構成で、動かなくなったときの切り分け表。 受付役(ゲートウェイ)はColima上のコンテナ、AI本体のOllamaはホストで常駐、pushとPR作成はホストの固定スクリプト(決まった手順を実行するプログラム)が行う。 経緯は開発日記のOpenClawが動かない5つの症状にある。
先に結論を書く。「動かない」は1つの症状ではなく、層が違う。 層を決めてから直す。
確かめる順番
入る前に1つ確かめる。接続先が本当にminiか。 ホスト名で入ると、MacBook Air自身を指していたことがあった(miniの改名のあと、ルーターの登録でAirが拾われた)。IPアドレスで入る。OpenClawのコンテナは、Airでは起動しない。
症状と原因の対応
| 症状 | まず見る | 原因だったもの | 直し方 |
|---|---|---|---|
| Discordのbotが無反応 | last reboot、colima status | OS更新の再起動のあと、Colimaが戻らなかった | colima start。約45秒でコンテナが正常になる |
| 返事が来ない、miniが熱い | ollama ps | 生成が終わらず、処理枠を占有していた | 受付役を止める。num_predict を入れる |
| 実行が途中で止まる | エラー文に XML syntax error | ローカルAIが </parameter> を書き忘れた | やり直す。編集を小さく分ける |
| 報告と結果が合わない | openclaw sessions tail | 実行場所の取り違え。失敗を報告に書かない | 報告ではなく実行記録で確かめる |
| PRができない | push-from-host.sh の出力 | 存在しないブランチ名の設定。ホストからworktreeが開けない | 下記 |
無反応: 再起動でColimaだけ戻らない
miniを再起動したあとに、何が戻って何が戻らなかったか。
| 部品 | 再起動後 |
|---|---|
| Ollama(LaunchAgentで常駐) | 戻る |
| PR監視(launchdで常駐) | 戻る |
| Colima | 戻らない |
Colimaが止まると、中のコンテナ(受付役)も落ちて、Discordの窓口が消える。 復旧は、miniに入って次を実行する。
export PATH=/opt/homebrew/bin:$PATH
colima start
CPUとメモリの設定は ~/.colima/default/colima.yaml に保存されているので、引数は要らない。
コンテナは再起動ポリシーで自動的に立ち上がる。
Colimaは、再起動後に自動で起動する設定になっていなかった。 brew services の一覧でも none だった。再起動後に戻っているかを見る仕組みは未実装で、実際に約2日気づかなかった。
生成が止まらない: 上限を入れる層
見えた挙動を並べる。
- shellの
timeoutでopenclaw agentを切っても、受付役の側の実行は止まらない。生成が約56分続いた maxTokens: 8192は、生成の長さの上限として効かなかったmodels.providers.ollama.models[2].params.num_predictを8192にすると効いた。64へ下げて流すと、64トークンで止まり(stopReason=length)、全体で30秒だった- 計測は、ゲートウェイの側で打ち切る
openclaw agent --timeout 秒を使い、終わりのあるプロンプトを1回だけ流す
[2] は、設定の中での並び順(私の構成の値)。自分の設定を見て合わせる。
受付役のコンテナが止まっているとき、設定は別のコンテナから書ける。--dry-run を付けると、書く前に検証できる。
docker run --rm --network none \
-v app_openclaw-state:/home/node/.openclaw \
codese/openclaw-agent:local \
openclaw config set "models.providers.ollama.models[2].params.num_predict" 8192
文脈の長さが頭打ちになるとき
文脈(AIが一度に読める量)の上限は、Ollamaの側だけでなく、OpenClawの側にもある。
32,000トークンで頭打ちになっていた原因は、Ollamaではなく、OpenClawの contextTokens だった。
docker exec openclaw-gateway openclaw config set \
"models.providers.ollama.models[2].contextTokens" 65536
変更は、そのまま反映される(再起動は要らない)。戻すときは32768。 128,000トークンまで広げる試験もしたが、メモリが約25GB、スワップが約540MBになったので採用していない。
ツール呼び出しが途中で止まる
ローカルの qwen3-coder:30b が、長い引数のツール呼び出しで閉じ印を書き忘れて、次のエラーで止まった。
XML syntax error ... element <parameter> closed by </function>
<や<=を含む編集が原因だと疑ったが、Ollamaへ直接渡すと通った。文字は原因ではない- 毎回は起きない。やり直すと通る
- 編集は、複数行の編集ツールではなく、
execのsedで1行ずつ置き換えるよう指示すると通った - 自動で直す側は、1回の修正の中で最大3回やり直す。やり直すときに「編集を小さく分ける」指示を足す
報告を鵜呑みにしない
ローカルのAIの報告が、実際とずれたことがある。
- 型検査とlintを、対象のアプリのフォルダではなくリポジトリの一番上で実行して失敗し、「権限の問題」と説明した
- レビューを呼ぶ道具の引数名を間違え、次は「道具が見つからない」で失敗し、1回目の報告は失敗を書かなかった
対策は2段にした。
- 指示書に書く。 「呼べなければ、PRを出す合図を置かない」。これで失敗を正直に報告するようになった。ただし頼んでいるだけで、守られる保証はない
- AIの判断に任せない。 マージの前に、ホストの固定スクリプトがレビューを呼ぶ。返答の最後の行が、ちょうど「判定: 問題なし」のときだけマージする。レビューを呼べない、差分が60KBを超える、形式が違う、のときはマージしない
報告は実行記録と照らす。openclaw sessions tail --agent 名前 で経過を追える。
PRにならない
pushは通ったのにPRの作成が失敗したときの原因は3つが重なっていた。
- ホストのgitが、コンテナの中で作られたworktreeを開けない。
.gitが/workspace/...を指しているのに、ホストにその場所が無い。pushの前にgit worktree repairを行う。以後はコンテナから見えなくなるので、再実行するときは、コンテナ側でgit -C /workspace/codese worktree repair /workspace/wt/名前をやり直す - 失敗の理由が
| tail -1で消えていた。 出力を残し、3回まで試す - launchdの設定に、存在しない
BASE_BRANCH=release/v1.2が残っていた。mainに直した。導入スクリプトは、値をplistに明示して書く
もう1つ、シェルの落とし穴がある。変数名の直後に日本語が続く書き方($MAX、)は、変数名の一部と読まれて、set -u で落ちた。 必ず ${MAX} と書く。ただし、これは直に書いた場合の話で、ヒアドキュメントの中では set -u でも止まらず、依頼文が欠けたまま実行された。再現した結果はbash 3.2の変数と日本語に残している。
結果が変なときは、渡したものを疑う
動いているのに結果がおかしいとき、モデルの出力を疑う前に、渡したものと、動かす環境を疑う。次の順で見る。
- 変更を、人が手順どおりに先に作った参照と比べる。同じなら、出力は悪くない。失敗は、出力の外にある
- 失敗した処理を、手で流し直す。通るなら、メモリの重なりや間隔を疑う。型検査の強制終了(137)は、待てば通った
- レビューの指摘が出たら、指摘が正しいかを、Issueの手順に照らして読む。正しければ、誤りは手順にある
3回の失敗がそれぞれ別の層だった例は、開発日記のminiに任せた初日、3回失敗したにある。
確かめていないこと
- 3回直しても通らず、あきらめる経路(偽物でしか試していない)
- 再起動後のColimaが戻っているかを見る仕組み(未実装)
やってはいけないこと
コンテナの中で codex exec を直接実行しない。 トークンの再発行が衝突して、refresh token was already used で落ちた。受付役を経由する openclaw agent --agent dev なら動く。
関連
- 開発日記: OpenClawが動かない5つの症状 — 5症状が起きた順番と、効かなかった設定
- 開発日記: miniに任せた初日、3回失敗した — 依頼文の欠け、メモリの重なり、Issueの設計の誤り
- bash 3.2の変数と日本語 — 変数の直後の日本語が壊れる再現と、見つけ方
- 鍵を渡さないpush設計 — 固定スクリプトの検査と、launchdで起動する仕組み
- ガードが素通りする書き方 — 止める仕組みが効いていなかった実例
- エージェントが止まるとき — 止まった理由を握りつぶさない考え方
- worktreeで分ける — 作業場所を分けるときの注意