【Bug已解决】Claude: "hooks not executing" / Pre/post hooks skipped — Claude Hooks 不执行解决方案
1. 问题描述
Claude Code 配置的 hooks(钩子)未执行或被跳过:
# Hooks 不执行 $ cat .claude/settings.json { "hooks": { "PreToolUse": "npm run lint", "PostToolUse": "npm run format" } } $ claude --auto-approve "修改 src/index.js" # lint 和 format 没有执行 # 或 hook 命令失败 $ claude "task" Error: Hook 'PreToolUse' failed npm run lint exited with code 1. # 或 hook 超时 $ claude "task" Error: Hook timeout PreToolUse hook exceeded 30000ms. # 或 hook 配置不识别 $ claude 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 .claude/settings.json # 步骤 2:正确格式 cat > .claude/settings.json << 'EOF' { "hooks": { "PreToolUse": ["npm run lint"], "PostToolUse": ["npm run format"] } } EOF # 步骤 3:验证 JSON python3 -m json.tool .claude/settings.json # 步骤 4:测试 claude --auto-approve "修改 src/index.js"方案二:使用正确的事件名
# 步骤 1:查看支持的事件名 claude --help | grep -i hook # 步骤 2:正确的事件名 # PreToolUse(不是 pre_tool_use) # PostToolUse(不是 post_tool_use) # Notification # Stop # 步骤 3:更新配置 cat > .claude/settings.json << 'EOF' { "hooks": { "PreToolUse": ["npm run lint"], "PostToolUse": ["npm run format"], "Stop": ["echo 'Done'"] } } EOF # 步骤 4:验证 claude --debug 2>&1 | grep -i hook方案三:检查 hook 命令
# 步骤 1:手动测试 hook 命令 npm run lint # 如果报错,修复 lint # 步骤 2:检查命令是否存在 which npm which eslint # 步骤 3:使用绝对路径 cat > .claude/settings.json << 'EOF' { "hooks": { "PreToolUse": ["/usr/local/bin/npm run lint"] } } EOF # 步骤 4:验证 claude --auto-approve "修改 src/index.js"方案四:增加 hook 超时
# 步骤 1:设置 hook 超时 cat > .claude/settings.json << 'EOF' { "hooks": { "PreToolUse": ["npm run lint"], "hookTimeout": 60000 } } EOF # 步骤 2:或环境变量 export CLAUDE_HOOK_TIMEOUT=60000 # 步骤 3:永久设置 echo 'export CLAUDE_HOOK_TIMEOUT=60000' >> ~/.zshrc source ~/.zshrc # 步骤 4:验证 claude --auto-approve "task"方案五:在根目录创建配置
# 步骤 1:确保在项目根目录 cd /project ls .claude/settings.json # 步骤 2:如果不存在,创建 mkdir -p .claude cat > .claude/settings.json << 'EOF' { "hooks": { "PreToolUse": ["npm run lint"], "PostToolUse": ["npm run format"] } } EOF # 步骤 3:验证加载 claude --debug 2>&1 | grep -i "hook\|settings" # 步骤 4:测试 claude --auto-approve "修改 src/index.js"方案六:更新版本
# 步骤 1:检查版本 claude --version # 步骤 2:更新 npm update -g @anthropic-ai/claude-code # 步骤 3:验证 hooks 支持 claude --help | grep -i hook # 步骤 4:测试 claude --auto-approve "task" claude --debug 2>&1 | grep -i hook4. 各方案对比总结
| 方案 | 适用场景 | 推荐指数 | 难度 |
|---|---|---|---|
| 方案一:配置格式 | 格式 | ⭐⭐⭐⭐⭐ | 低 |
| 方案二:事件名 | 名称 | ⭐⭐⭐⭐⭐ | 低 |
| 方案三:检查命令 | 命令 | ⭐⭐⭐⭐⭐ | 低 |
| 方案四:超时 | 超时 | ⭐⭐⭐⭐ | 低 |
| 方案五:根目录 | 位置 | ⭐⭐⭐⭐⭐ | 低 |
| 方案六:更新 | 版本 | ⭐⭐⭐ | 低 |
5. 常见问题 FAQ
5.1 Hooks 是什么
Claude Code 的钩子机制,在工具调用前后自动执行命令。
5.2 支持哪些 hook 事件
PreToolUse: 工具调用前PostToolUse: 工具调用后Notification: 通知时Stop: 会话结束时
5.3 hooks 配置在哪里
.claude/settings.json中的hooks字段。
5.4 如何验证 hooks 执行
claude --debug 2>&1 | grep -i hook5.5 hook 命令失败怎么办
检查命令是否存在,手动运行测试,使用绝对路径。
5.6 hook 超时多少
默认 30 秒。通过hookTimeout或CLAUDE_HOOK_TIMEOUT调整。
5.7 配置不被加载
确保在项目根目录,检查 JSON 格式,使用claude --debug | grep settings。
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. CLAUDE_HOOK_TIMEOUT=60000 环境变量 □ 9. 在根目录创建 .claude/settings.json □ 10. claude --debug | grep hook 验证6. 总结
- 根本原因:Hooks 不执行最常见原因是配置格式错误(30%)和事件名错误(25%)
- 最佳实践:使用
python3 -m json.tool验证配置,使用正确的事件名(PreToolUse/PostToolUse) - 命令检查:手动运行 hook 命令,使用绝对路径,增加
hookTimeout - 配置位置:在项目根目录
.claude/settings.json中配置 - 最佳实践建议:使用
claude --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[重新创建 settings.json] F --> G[claude --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/.claude/] R -->|是| T[更新版本] S --> G T --> U[npm update -g claude-code] U --> G G --> V{hooks 执行?} V -->|是| W[✅ 问题解决] V -->|否| X[检查 hooks 值格式] X --> Y[改为数组: ["command"]] Y --> G W --> Z[长期: 正确格式 + 事件名 + 命令] Z --> AA[✅ 长期方案]