Error: stdin is not a terminal
結論
対話用のコマンドを端末の無い場所で実行した状態。CIやスクリプトでは exec を使う。
確認した版
Codex CLI v0.153.0
確認日
2026年9月3日
最終更新
2026年9月3日
根拠
実機で確認
エラー文字列
Error: stdin is not a terminal
⚠️ 標準エラーに出て、終了コードは 1 です。 手元では動くのに CI だけ落ちる、という形で現れます。
何が起きているか
選択画面を出すコマンドを、端末の無い場所で実行しました。
codex resume は「どのセッションを再開するか」を選ばせます。選ばせる相手(端末)が無いので、始める前に止まります。
⭐ CI・スクリプト・パイプ・cron は、いずれも端末を持ちません。
v0.149.0 で実測した対応表です。
| コマンド | 端末なしで動くか |
|---|---|
codex exec "..." |
✅ 動く(非対話用) |
codex resume --last |
❌ Error: stdin is not a terminal |
codex resume <ID> |
❌ 同上 |
codex(対話UI) |
❌ 同上 |
直し方
1. CI・スクリプトでは exec を使う
codex exec "テストを実行して結果をまとめて"
⭐ exec は端末を必要としません。 出力もそのまま標準出力に流れるので、ログに残ります。
2. 端末があるかを先に判定する
対話用と非対話用を1つのスクリプトで共用するなら、分岐させます。
macOS / Linux
if [ -t 0 ]; then
codex resume --last
else
codex exec "$PROMPT"
fi
Windows(PowerShell)
if ([Environment]::UserInteractive -and -not [Console]::IsInputRedirected) {
codex resume --last
} else {
codex exec $Prompt
}
3. 手元で「CI と同じ状態」を再現する
⚠️ 手元で動くことは、CI で動く理由になりません。 標準入力を切って試すと、同じ失敗を手元で起こせます。
macOS / Linux
codex resume --last < /dev/null
Windows(PowerShell)
cmd /c "codex resume --last < NUL"
これで Error: stdin is not a terminal が出れば、CI で落ちる原因はこれです。
再発防止
- CI で対話用コマンドを呼ばない。 再開が必要ならセッションIDを保存して
execに渡す - スクリプトは「端末があるか」で分岐させる
- 手元で確認するときは標準入力を切って試す。そこが CI との唯一の違いであることが多い