minorinfra-failureunverifiedcollected
無人の文字起こしが「user cancelled」で止まり、機械作業をLLMから外した(未検証の報告)
面接の録音を議事録にする定時実行のパイプラインが、朝に2回続けて、文字起こしの開始前に「user cancelled」で止まった。キャンセルできる人間はどこにもいない無人の実行だった。
原因
その朝はClaudeの利用枠が切れ、フェイルオーバーでCodexが引き継いでいた。codex exec 経由ではMCPのツール一覧の取得は通るが、文字起こしツールの実呼び出しだけが「user cancelled MCP tool call」で失敗した。同じサーバー・同じツール・同じ引数を、Codexを通さず直接呼ぶと成功した。筆者は承認の経路を疑ったが、内部の原因までは断定していない。
結果
2回とも文字起こしが始まらず、パイプラインが止まった。approval_policy="never" やsandboxの指定を変えても同じで、筆者は2026年7月時点の手元のCodex CLIでは、この経路を設定で開ける方法を見つけられなかった。
対策
筆者はCodexの設定を直すのをやめ、切り分けのために書いた約50行のMCPクライアントを、文字起こし専用の決定的なスクリプトにした。LLMには完成済みの文字起こしテキストだけを渡し、話者の推定や構造化だけを任せる。リトライは壊れたチャンクだけで済み、成功した分はファイルに残るので再実行時に飛ばせる。
何が起きたか
筆者は、面接の録音を議事録にする自動パイプラインを、隠しプロセスの定時実行で 動かしていた。録音をffmpegで30秒ずつのチャンクに割り、エージェントCLI (Claude CodeやCodex)がMCP経由でローカルのWhisperサーバー(Voicebox)を 1チャンクずつ呼んで文字起こしし、そのまま議事録に構造化する。ある朝、 この処理が2回続けて、文字起こしの開始前に「user cancelled」で止まった。
現場の混乱
キャンセルできる人間はいないのに、ログには「ユーザーが止めた」と残っていた。
実行台帳を見ると、その朝はClaudeの利用枠が切れて飛ばされ、Codexが引き継いで
いた。失敗したのはCodexの回だけだった。最小の再現では、Codexにツール一覧を
聞かせると通るが、voicebox.transcribe を呼ばせると
「user cancelled MCP tool call」で失敗した。approval_policy="never" に
しても、sandboxの指定を変えても結果は同じだった。
原因
筆者はCodexを外し、同じサーバーへ同じ引数を、MCPのstreamable HTTPで直接
送った。結果はすぐに成功した。これでVoicebox単体の故障ではなく、Codexを
含む呼び出し経路に依存する問題だと切り分けた。非対話の codex exec には
確認する人がいないため承認の経路と衝突している、という仮説を立てたが、
内部の実装は観測できないので、原因はそれ以上名指ししていない。
対策
筆者はCodexの設定を掘るのをやめた。直しても、判断の要らない「30秒の音声を 順に渡して結果をつなぐ」仕事を毎回LLMに頼む形が残るからである。チャンクを 飛ばしても気づかない、途中で「以降は省略します」と言い出せる、 プロバイダごとにMCPの接続や承認の仕様が違う、という壊れ方もある。そこで、 切り分けに使った約50行のMCPクライアントを文字起こし専用のスクリプトにし、 LLMには完成した文字起こしだけを渡すようにした。MCPを呼ばないので、 フェイルオーバー先がどのCLIでも今回の問題は起きない。
判断の要らない機械作業は、エージェントのツール呼び出しに載せずにコードで 書くほうが、確かめやすく、やり直しもしやすい。