codex execが「Reading additional input from stdin…」と出たまま止まるときは、コマンドの末尾に< /dev/nullを付けると回避できる。
先に要点をまとめておく。
- 対処:
codex exec "プロンプト" < /dev/nullのように、標準入力を空にして実行する - 原因: プロンプトを引数で渡していても、標準入力がターミナルに直結していないと、Codexは標準入力を最後まで読もうとする
- 起きやすい場面: スクリプトや別のツール経由で
codex execを呼んだとき。毎回は起きない - このメッセージ自体は毎回出る表示で、出ただけでは異常ではない
400秒たっても応答が返ってこなかった
ブログや動画の台本チェックには、OpenAIのCodex CLIのcodex execコマンド(ターミナルで動くAIエージェント)を使っている。この日はYouTube Shortsの台本を採点してもらうところで、いつも通り台本のテキストをプロンプトにそのまま埋め込んで実行した。ターミナルの表示は止まったまま、400秒以上たっても応答が返ってこなかった。
ログに唯一出ていたのが「Reading additional input from stdin…」という一行。この時点で「これが犯人だ」と決めつけかけた。
「標準入力待ち」だと思って、直した
文字通り読めば、標準入力を待っているように見える。だったら塞げばいいはずだと思い、codex exec "プロンプト" < /dev/nullのように末尾に < /dev/null を付けて実行し直した。空の入力をあらかじめ渡しておくことで、入力待ちにならないようにする書き方だ。結果、今度はすんなり動いた。
「やっぱり標準入力待ちが原因だった」。そう思って、そのまま記事にしかけた。
書く前に、念のため再現させてみた
過去に何度か「唯一目に見えた手がかり」を犯人扱いして外したことがある。今回もその匂いがしたので、公開前に同じ条件で3回試すことにした。
< /dev/null を付けずに、さっきと同じプロンプトを3回実行した。結果は6秒・6秒・45秒。3回とも普通に完走した。
少なくとも、< /dev/null を付けないと必ず止まるわけではなかった。「標準入力待ちで止まっていた」という仮説は、そのままでは成立しなくなった。ここで一度、記事にするのをやめた。
本家のGitHub issueに、同じ現象がそのまま報告されていた
自分の手元だけでは埒が明かないので、Codex CLIのGitHubリポジトリ(openai/codex)のissueを検索してみた。すると、まさに同じ文言・同じ状況を報告しているissueが見つかった(#27019、重複扱いで#20919・#19945にも同種の報告あり)。
issueのコメントには、ソースコードの該当箇所まで示されていた。codex-rs/exec/src/lib.rsのresolve_root_promptという関数は、プロンプトを引数で渡していても、標準入力が非TTY(ターミナルに直結していない)だと判断すると、read_prompt_from_stdinを呼んで標準入力を読みにいく。この読み込みがstd::io::stdin().read_to_end()で、タイムアウトも「データが来る見込みがあるか」の確認もなく、無条件に実行される。
問題は、標準入力が「書き込み側のプロセスはまだ生きているのに、データもEOFも送ってこない」状態のパイプだったときだ。read_to_end()はデータが来るかEOFが来るまで戻ってこないので、この条件に当たると永遠に待ち続ける。
ただし同じissue内でも、報告者によって引き金が2パターンに分かれていた。最初の投稿者が踏んだのはTERM=dumbという条件で、この人の環境では< /dev/nullを付けても直らなかった。一方、別のコメント者が改めて検証したのは「パイプの書き込み側が生きたままデータが来ない」パターンで、こちらでは< /dev/nullが確実に効いていた。ログの文言も直った条件も後者の報告に近いので、今回の400秒もこちらに当てはまっていた可能性が高い。
なぜ再現したりしなかったりしたのか(ここからは推測)
ここから先は、issueの報告と自分の状況を重ねただけの推測で、パイプの中身を直接観測して確かめたわけではない。自分の環境では、Codexを自分のターミナルから直接ではなく、別のツール(Claude Code)のBash実行機能経由で呼び出している。この場合、子プロセスの標準入力は呼び出し元から継承される。継承されたパイプがちょうど「書き込み側は生きているがデータが来ない」状態になっているかどうかは、その時々の実行タイミングによって変わるのではないかと考えている。だとすれば、3回試して3回とも完走した、という結果も矛盾しない。運が悪いタイミングに当たると止まり、当たらなければ普通に動く、という間欠的な不具合だったことになる。
< /dev/null を付けると直った理由もこれで説明がつく。/dev/null を明示的に標準入力に指定すると、読み込みは即座にEOFを返す。「書き込み側が生きたままデータが来ない」という条件そのものが発生しなくなるので、待ち続けることがなくなる。
「唯一見えたログ」は、的外れではなかったようだ
今回に限って言えば、最初に疑った「Reading additional input from stdin…」というログは、的外れではなかったようだ。ただ、公開前の3回の再現テストだけでは「標準入力待ちが原因」とは言い切れず、あの時点で記事にしていたら、確信の持てない仮説を事実のように書くところだった。自分のパイプの状態を実際に覗いたわけではないので「確定」とまでは言えないが、執筆時点(2026年9月)でCodex CLIに未修正で残っているバグ(readiness check・タイムアウトの欠如)が、有力な説明として見つかった。GitHub上ではすでに、200ms程度の準備確認を入れる修正を試したブランチがコメント欄で共有されている(まだ本体には取り込まれていない)。
再現しなかったからといって、疑いが完全に外れたとは限らない。条件次第でしか起きない不具合は、目の前の再現結果だけで白黒つけず、公式のissueトラッカーまで見に行く価値があった。実務上の対処は変わらず、codex execをスクリプトや別ツール経由で呼ぶときは< /dev/nullを付けている。