故障处理
Codex 任务完成没有通知?桌面提醒、终端事件与触发验证
Codex 完成后没提醒、notify 手动能运行却不触发?按桌面应用、CLI 和 IDE 选择通知通道,核对配置、焦点与系统显示;分别验证回合结束、通知送达和任务真正完成。
Codex 已经回完,系统却没有弹出提醒;或者 notify 脚本手动能运行,真实对话结束后却没反应。先分别核对三件事:这一轮是否结束、提醒通道是否触发、通知是否实际显示。 任务的代码、文件和业务结果还要另外验收,不能靠一条通知证明已经做对。
本文处理 Codex 任务完成没有通知、codex notify not working 和终端提醒不生效。目标是让你在切走窗口后知道何时回来查看,并能定位失败阶段。若定时任务本身没有运行记录,先看定时任务到点没运行排查,不要先改通知脚本。
先按现象找下一步
| 你看到什么 | 下一步及应取得的证据 |
|---|---|
| 聊天仍在运行、等授权或等回答 | 先核该轮状态;完成提醒与权限、问题提醒不是同一种事件 |
| 桌面应用有回复,但没弹窗 | 第 2 步核应用设置、前后台条件及系统通知记录 |
| CLI 在当前窗口没提醒,切走后可能会有 | 第 3 步核焦点条件和终端支持,不先判断事件丢失 |
| 外部脚本手动成功,真实回合后没记录 | 第 4 步分开验证配置来源、参数和实际调用 |
| 已看到提醒,但内容没做完 | 第 5 步核任务产物;回合结束不等于任务验收通过 |
1. 先确认客户端与通知通道
适用条件: 还不确定该改哪个开关,或正在照搬其他人的配置。先记下客户端、版本、运行主机和所用终端;CLI 可在系统终端运行 codex --version。WSL、SSH、容器与本机分别确认,IDE 的远程工作区也不能只按窗口所在电脑判断。
当前官方通知说明按使用界面区分控制入口:
| 使用位置 | 先核对什么 |
|---|---|
| 桌面应用 | Settings 中的回合完成提醒,以及单独的权限、问题通知;官方当前以 ChatGPT 桌面应用描述这组设置 |
| CLI 交互终端 | TUI 内置终端通知,或配置为执行外部程序的通知;它们是两条不同路线 |
| IDE 扩展 | 官方说明没有独立通知控制;外部通知配置在实际连接的 Codex 主机上 |
| ChatGPT Work 网页 | Settings → Notifications 中账号实际可用的类别与渠道;不套成本地 CLI 或所有 Codex 云任务的统一入口 |
预期结果: 能明确“哪一端产生事件、哪一个应用或终端负责显示”。入口与文档不同就记录当前版本和可见项,不把缺少某个开关直接解释成产品完全不支持。先用已有的合适通道;桌面内置提醒或 TUI 通知并不要求写脚本、装 MCP 或接手机推送。
下面的外部 notify 按官方高级配置目前只处理 agent-turn-complete。它表示一个回合结束,不是“测试全部通过”“PR 已创建”或“业务全部完成”。需要等待授权时,也不要期待这个完成事件代替授权提醒。
2. 桌面应用:先对照前后台条件与系统显示
适用条件: 使用桌面应用的内置提醒。无需执行后面的 Python 探针。
打开当前应用 Settings,核对回合完成提醒是否为关闭、仅后台或始终显示;权限和问题通知分开核对。只调整你确实需要的这一项,保留原设置。若本版本没有这些选项,记录“入口尚未确认”,不要转而修改不相干的 CLI 配置。
再在操作系统中核对实际负责显示的应用是否允许通知,以及当前免打扰、专注模式、通知横幅和通知中心的表现。系统有记录但没出现横幅,与完全没有记录应分别记下;没有声音也不能单独证明没有通知。
验证: 按第 5 步用同一非敏感短任务分别测前台与后台。仅后台模式下,应用仍在前台时没有弹窗,可能符合设置;必须先确认切走时该轮还没结束,才能把这次算作后台用例。
若当前界面提供 Activity,可用它核对运行、未读或等待输入的聊天。Activity 状态只能补充任务线索,不证明系统已经显示通知,也不证明任务内容正确。系统权限被组织限制时记录原因交管理员,不靠管理员启动或关闭防护制造弹窗。
3. CLI:区分 TUI 通知、焦点条件与终端能力
适用条件: 使用交互式 CLI,希望当前终端提供提醒。外部 notify 的脚本设置不会自动修好 TUI 的显示问题。
在确认属于当前执行主机的用户配置中,核对下面这组键。以下是一个只关注回合结束的示例;合并到已有的 [tui] 表,不要重复创建表或覆盖整份配置:
[tui]
notifications = ["agent-turn-complete"]
notification_method = "auto"
notification_condition = "unfocused"
配置参考说明:通知可启用或按事件筛选;方法为 auto、osc9 或 bel;焦点条件为 unfocused 或 always,默认是 unfocused。因此,一直盯着有焦点的终端等提醒,不一定符合当前触发条件。
在 auto 下,官方说明优先使用 OSC 9,回退到 BEL。发出终端控制序列,不保证当前终端会显示系统横幅或发声。 终端应用、复用器、远程链路和系统通知设置都可能影响最终表现;先核当前终端自己的通知或铃声能力,不连续切换所有方法来碰运气。
预期结果: 已确认当前会话的加载环境、选定事件、方法与焦点条件,再做一次符合条件的实际回合。支持时可在 CLI 聊天内用 /debug-config 查配置层和受管来源;它不是所有通知键的完整有效值导出器。配置路径或覆盖仍不清楚时,转到config.toml 不生效排查。
前台无提醒、失焦后有提醒时,按实际设置解释,不直接报故障。两种情况都没有时保留终端、系统、CLI 版本及具体结果,核所选事件与显示能力;不要把 BEL 没声音直接定位成 Codex 没派发。此处的 TUI 配置也不是 codex exec 通知行为的实测保证,非交互执行应另核当前版本及exec 的输出和终态。
4. 外部 notify:手动调用与真实事件分别验证
适用条件: 你确实选用外部程序,或已有脚本手动正常、真实回合却不触发。桌面内置和 TUI 路线可以直接跳到第 5 步。
先核配置位置。当前官方明确:项目级 .codex/config.toml 会忽略 notify,建议把此类机器本地配置放在用户层。自定义配置目录、profile、启动覆盖及 IDE 连接主机仍要分别检查;不要因某份文件有一行 notify 就宣称本次已加载。TOML 的表头会影响后续键所属位置,根级 notify 不能误写成 [tui] 下的键。
官方说明外部程序收到一个 JSON 参数。其中可能有用户输入、最后回复和工作目录。排查时不用原始消息做测试,不把整份参数写日志、拼进 shell 命令或发到 webhook;也不默认安装第三方通知工具。
可选探针:只记固定事件标记,不弹窗
在仓库外创建一个全新的独立目录,将下面保存为 notify_probe.py,不覆盖已有脚本。它使用 Python 3 标准库,仅追加同目录的 notify-probe.jsonl;日志只有时间、固定事件和标记,不记录消息、路径或会话 ID。目录须由你控制且不与别人共用。
import json
import sys
from datetime import datetime, timezone
from pathlib import Path
if len(sys.argv) != 2:
raise SystemExit("Expected one JSON argument")
try:
payload = json.loads(sys.argv[1])
except json.JSONDecodeError:
raise SystemExit("Invalid JSON payload")
if not isinstance(payload, dict):
raise SystemExit("Expected a JSON object")
if payload.get("type") != "agent-turn-complete":
print("IGNORED_EVENT")
raise SystemExit(0)
record = {
"time_utc": datetime.now(timezone.utc).isoformat(),
"event": "agent-turn-complete",
"marker": "NOTIFY_PROBE_V1",
}
log = Path(__file__).resolve().with_name("notify-probe.jsonl")
with log.open("a", encoding="utf-8") as stream:
stream.write(json.dumps(record) + "\n")
print("NOTIFY_PROBE_RECORDED")
先在该执行主机确认已有的 Python 3 可运行;不为这个探针全局安装或调整 PATH。下面是 Bash/zsh 的合成参数测试,将脚本路径换成实际值,解释器使用刚确认的启动方式:
python3 "/new/empty/notify-check/notify_probe.py" '{"type":"agent-turn-complete"}'
预期结果: 输出 NOTIFY_PROBE_RECORDED,新目录日志增加一行。这只证明刚才的手动调用能够解析参数并写标记,没有测试真实 Codex 派发,更没有测试系统弹窗。没有弹窗是这个探针的设计。Windows 使用本机已核实的解释器及 shell 参数规则,不把 Bash 引号用法当 PowerShell 各版本的实测结论。
需要临时接入当前 CLI 的通知链时,先在本机保留原来 notify 的值与位置,不覆盖已有业务通知;优先在已获准的隔离测试配置中操作。下面是根级 TOML 示例,必须换成该主机真实存在的解释器与脚本绝对路径,放在任何表头之前;路径用 / 只是示意,不直接用于 Windows:
notify = ["/absolute/path/to/python3", "/new/empty/notify-check/notify_probe.py"]
不想改写用户配置时,CLI 支持单次启动覆盖。在独立测试目录内,Bash/zsh 可用下面的命令启动测试会话,先替换两个绝对路径;值是 TOML,外层引号用于保留整个参数:
codex --config 'notify=["/absolute/path/to/python3","/new/empty/notify-check/notify_probe.py"]'
这仅覆盖本次进程的通知命令,不隔离其他用户配置、hooks 或外部副作用;有业务流程时只在已获准的无业务副作用测试环境中执行。启动后再发送第 5 步的短请求。测试前记录日志原有行数与时间,手动测试的一行不算真实触发;验证期间不要再手动调用,也不要让 Codex 自己运行探针、写日志来“证明成功”。新增的对应时间记录才是这次链路的证据,仍不能单靠日志证明调用者身份或屏幕送达。
没有新记录时,先区分配置未进入会话、事件不匹配、程序启动失败、参数错误与日志写入失败。按实际错误核路径、解释器、依赖及允许写入的目录,不默认添加执行权限、绕执行策略或放行防护。命令本身不可用时看任务环境与 PATH;不要一开始就删配置重装。
探针有记录、原通知程序却没提醒时,继续核原程序自身的本地显示环节,用固定无敏感文本手动验证,再核真实回合。不要让模型代发通知代替完成事件,也不要把用户输入或最后回复作为默认通知正文。事件探针不能代替对原通知程序的送达验证。
5. 用同一短任务核对触发、送达与任务验收
适用条件: 已选好一条通知路线,需要确认当前组合真实可用。下面是真实 Codex 请求,会使用账号额度;先用非敏感短请求,不读取项目或调用外部工具:
这是一轮完成提醒检查。只回复一行:NOTIFY_TURN_DONE。
不要读取、修改或创建文件,不运行命令,不调用外部工具,也不要自行发送通知。
记录发起时间、实际回复结束时间、所选通道与显示结果。若要测后台或失焦,发出后及时切走;若回复在切走前已结束,这次不能算后台测试。一次只比较一个条件:先核前台/后台或焦点,再查看免打扰下的显示差异,不同时改配置、终端和脚本。
| 这次取得的证据 | 能说明什么,以及下一步 |
|---|---|
| 手动探针成功 | 仅手动路径通过;继续验证真实回合,不把旧日志算新触发 |
| 真实回合后新增对应探针记录 | 外部处理链走到了写标记这一步;原通知程序和系统显示仍要另验 |
| 内置提醒或原通知实际出现 | 所测端、焦点和系统条件下有显示;记录时间和内容标记,不外推全平台 |
| 系统通知中心有记录,但没横幅/声音 | 按显示设置继续查,不重建任务或认证 |
| 有回复却仍无通知 | 核当前通道、事件与条件,再保留版本和原始错误;没通知不证明没有运行 |
| 收到完成提醒,但原任务缺产物 | 回到任务没做完的状态与验收,不把事件名称当业务完成证明 |
短请求通过后,再核原任务是否已经完成要求的文件、测试或交付操作。休眠、关机或应用退出时任务是否继续执行,是另一层问题;不要把这种条件下没提醒直接归为通知故障。定时运行的结果位置与报告条件仍按原定时任务指南检查。
结束测试: 恢复临时修改的通知值和开关,只移除自己创建的探针配置;已有业务通知、其他配置和日志保留。若用了独立测试目录,确认没有仍在使用它的测试会话再清理,不删除真实 Codex 会话或历史记录。本文的 notify 不是 hooks 配置;只有实际使用 hooks 时才转到hooks 匹配、加载与派发排查。
隔离验证结果与未实测范围
本文于 2026-10-22 重新读取官方通知、配置参考和配置诊断说明。用 macOS、Python 3.13.7 在独立目录运行了文中探针:正确的合成完成事件写入固定标记,其他事件不写入,缺参数、损坏 JSON 和非对象参数返回非零;重复有效调用追加记录而不覆盖旧行。含虚构消息、路径及 ID 的合成参数没有进入日志。TOML 示例可解析,并验证了表头导致根级键落入错误层级的差别;单次覆盖命令核对官方说明与本机帮助,未启动真实测试会话。
本机 CLI 版本检查为 codex-cli 0.163.0-alpha.11.1;这不是这些功能的最低版本承诺。本次未调用真实模型,未实测真实回合派发、桌面设置界面、系统弹窗或声音、Windows/WSL/SSH、IDE 远程及网页推送,也未修改用户通知开关或现有 Codex 配置。合成参数测试不冒充真实事件或通知送达;各客户端差异来自当前官方资料,实际入口仍需按读者版本核对。
完成标准: 你能说清当前端和通道、触发条件、实际取得的证据与未验证项,并将原任务验收单独列出。仍失败时提供脱敏的版本、运行主机、终端、配置键所在层、测试时间、前后台条件和原始错误;不要公开整份配置、原始 JSON、私有回复或 webhook 凭据。