【Bug已解决】codex: "hooks not executing" / Pre/post hooks skipped — CodeX Hooks 不执行解决方案

1. 问题描述

CodeX CLI 配置的 hooks(钩子)未执行或被跳过:

# Hooks 不执行
$ cat .codex/config.json
{
  "hooks": {
    "PreToolUse": "npm run lint",
    "PostToolUse": "npm run format"
  }
}
$ codex --auto-approve "修改 src/index.js" --max-turns 5
# lint 和 format 没有执行

# 或 hook 命令失败
$ codex "task"
Error: Hook 'PreToolUse' failed
npm run lint exited with code 1.

# 或 hook 超时
$ codex "task"
Error: Hook timeout
PreToolUse hook exceeded 30000ms.

# 或 hook 配置不识别
$ codex
Error: Unknown hook event: 'pre_tool_use'
# 配置名称错误

这个问题在以下场景中特别常见:

  • hook 配置格式错误
  • hook 事件名称错误
  • hook 命令不存在
  • hook 命令超时
  • 配置文件不被加载
  • 版本不支持 hooks

2. 原因分析

原因分类表

原因分类具体表现占比
配置格式错误JSON约 30%
事件名错误pre_tool_use约 25%
命令不存在EACCES约 20%
超时30s约 10%
配置不加载位置约 10%
版本不支持旧版约 5%

3. 解决方案

方案一:检查 hook 配置格式(最推荐)

# 步骤 1:检查配置
python3 -m json.tool .codex/config.json

# 步骤 2:正确格式
cat > .codex/config.json << 'EOF'
{
  "model": "o1",
  "hooks": {
    "PreToolUse": ["npm run lint"],
    "PostToolUse": ["npm run format"]
  }
}
EOF

# 步骤 3:验证 JSON
python3 -m json.tool .codex/config.json

# 步骤 4:测试
codex --auto-approve "修改 src/index.js" --max-turns 5

方案二:使用正确的事件名

# 步骤 1:查看支持的事件名
codex --help | grep -i hook

# 步骤 2:正确的事件名
# PreToolUse(不是 pre_tool_use)
# PostToolUse(不是 post_tool_use)
# Notification
# Stop

# 步骤 3:更新配置
cat > .codex/config.json << 'EOF'
{
  "model": "o1",
  "hooks": {
    "PreToolUse": ["npm run lint"],
    "PostToolUse": ["npm run format"],
    "Stop": ["echo 'Done'"]
  }
}
EOF

# 步骤 4:验证
codex --debug 2>&1 | grep -i hook

方案三:检查 hook 命令

# 步骤 1:手动测试 hook 命令
npm run lint
# 如果报错,修复 lint

# 步骤 2:检查命令是否存在
which npm
which eslint

# 步骤 3:使用绝对路径
cat > .codex/config.json << 'EOF'
{
  "hooks": {
    "PreToolUse": ["/usr/local/bin/npm run lint"]
  }
}
EOF

# 步骤 4:验证
codex --auto-approve "修改 src/index.js" --max-turns 5

方案四:增加 hook 超时

# 步骤 1:设置 hook 超时
cat > .codex/config.json << 'EOF'
{
  "hooks": {
    "PreToolUse": ["npm run lint"],
    "hookTimeout": 60000
  }
}
EOF

# 步骤 2:或环境变量
export CODEX_HOOK_TIMEOUT=60000

# 步骤 3:永久设置
echo 'export CODEX_HOOK_TIMEOUT=60000' >> ~/.bashrc
source ~/.bashrc

# 步骤 4:验证
codex --auto-approve "task" --max-turns 5

方案五:在根目录创建配置

# 步骤 1:确保在项目根目录
cd /project
ls .codex/config.json

# 步骤 2:如果不存在,创建
mkdir -p .codex
cat > .codex/config.json << 'EOF'
{
  "hooks": {
    "PreToolUse": ["npm run lint"],
    "PostToolUse": ["npm run format"]
  }
}
EOF

# 步骤 3:验证加载
codex --debug 2>&1 | grep -i "hook\|config"

# 步骤 4:测试
codex --auto-approve "修改 src/index.js" --max-turns 5

方案六:更新版本

# 步骤 1:检查版本
codex --version

# 步骤 2:更新
npm update -g @openai/codex

# 步骤 3:验证 hooks 支持
codex --help | grep -i hook

# 步骤 4:测试
codex --auto-approve "task"
codex --debug 2>&1 | grep -i hook

4. 各方案对比总结

方案适用场景推荐指数难度
方案一:配置格式格式⭐⭐⭐⭐⭐
方案二:事件名名称⭐⭐⭐⭐⭐
方案三:检查命令命令⭐⭐⭐⭐⭐
方案四:超时超时⭐⭐⭐⭐
方案五:根目录位置⭐⭐⭐⭐⭐
方案六:更新版本⭐⭐⭐

5. 常见问题 FAQ

5.1 Hooks 是什么

CodeX CLI 的钩子机制,在工具调用前后自动执行命令。

5.2 支持哪些 hook 事件

  • PreToolUse: 工具调用前
  • PostToolUse: 工具调用后
  • Notification: 通知时
  • Stop: 会话结束时

5.3 hooks 配置在哪里

.codex/config.json 中的 hooks 字段。

5.4 如何验证 hooks 执行

codex --debug 2>&1 | grep -i hook

5.5 hook 命令失败怎么办

检查命令是否存在,手动运行测试,使用绝对路径。

5.6 hook 超时多少

默认 30 秒。通过 hookTimeoutCODEX_HOOK_TIMEOUT 调整。

5.7 配置不被加载

确保在项目根目录,检查 JSON 格式,使用 codex --debug | grep config

5.8 hooks 值是数组还是字符串

应该是数组:["npm run lint"],不是字符串 "npm run lint"

5.9 可以配置多个 hook 吗

是的。["npm run lint", "npm run typecheck"]

5.10 排查清单速查表

□ 1. python3 -m json.tool 验证 JSON
□ 2. 事件名: PreToolUse/PostToolUse(大写)
□ 3. hooks 值是数组: ["command"]
□ 4. 手动测试 hook 命令
□ 5. which npm 检查命令存在
□ 6. 使用绝对路径
□ 7. hookTimeout: 60000 增加超时
□ 8. CODEX_HOOK_TIMEOUT=60000 环境变量
□ 9. 在根目录创建 .codex/config.json
□ 10. codex --debug | grep hook 验证

6. 总结

  1. 根本原因:Hooks 不执行最常见原因是配置格式错误(30%)和事件名错误(25%)
  2. 最佳实践:使用 python3 -m json.tool 验证配置,使用正确的事件名(PreToolUse/PostToolUse
  3. 命令检查:手动运行 hook 命令,使用绝对路径,增加 hookTimeout
  4. 配置位置:在项目根目录 .codex/config.json 中配置
  5. 最佳实践建议:使用 codex --debug 2>&1 | grep -i hook 验证 hooks 执行

故障排查流程图

flowchart TD
    A[Hooks 不执行] --> B[python3 -m json.tool 验证]
    B --> C{JSON 有效?}
    C -->|否| D[修复 JSON 格式]
    C -->|是| E[检查事件名]
    D --> F[重新创建 config.json]
    F --> G[codex --debug | grep hook]
    E --> H{名称正确?}
    H -->|否| I[改为 PreToolUse/PostToolUse]
    H -->|是| j[检查命令]
    I --> G
    j --> K[手动运行 hook 命令]
    K --> L{命令成功?}
    L -->|否| M[修复命令或使用绝对路径]
    L -->|是| N[检查超时]
    M --> G
    N --> O{hook 超时?}
    O -->|是| P[hookTimeout: 60000]
    O -->|否| Q[检查配置位置]
    P --> G
    Q --> R{在根目录?}
    R -->|否| S[移到 /project/.codex/]
    R -->|是| T[更新版本]
    S --> G
    T --> U[npm update -g @openai/codex]
    U --> G
    G --> V{hooks 执行?}
    V -->|是| W[✅ 问题解决]
    V -->|否| X[检查 hooks 值格式]
    X --> Y[改为数组: ["command"]]
    Y --> G
    W --> Z[长期: 正确格式 + 事件名 + 命令]
    Z --> AA[✅ 长期方案]

更多推荐