Skip to content
看累了听个音乐吧

8.5 常见错误与调试

8.5 常见错误与调试

Hook 不生效?先过这个清单

Hook 写完发现没有反应,90% 的情况是以下几个原因之一。


问题一:脚本没有执行权限

最常见的问题,没有之一。

bash
# 检查权限
ls -la .claude/hooks/

# 应该看到 -rwxr-xr-x,如果是 -rw-r--r-- 就说明没有执行权限
# 修复:
chmod +x .claude/hooks/your-hook.sh

问题二:jq 没有安装

很多 Hook 脚本用 jq 解析 JSON 输入,如果没装,脚本会悄悄失败。

bash
# 检查是否安装
which jq

# 安装
brew install jq          # macOS
apt-get install jq       # Ubuntu/Debian

问题三:settings.json 格式错误

JSON 格式错误会导致整个配置不加载,所有 Hook 都不生效。

bash
# 验证 JSON 格式是否正确
cat ~/.claude/settings.json | jq .

# 如果报错,说明有格式问题
# 常见错误:多了/少了逗号,引号不匹配,嵌套括号不对

问题四:matcher 没匹配上

Hook 有 matcher 字段,只有工具名匹配的调用才会触发。

bash
# 检查你的 matcher 是否正确
# "Edit|Write" 匹配 Edit 和 Write 工具
# "Bash" 匹配 Bash 工具
# "" 空字符串匹配所有工具

# 临时改成空字符串测试是否是 matcher 问题

/hooks 命令检查配置

在 Claude Code 会话里输入:

/hooks

会打开一个交互式界面,显示所有已加载的 Hook:

  • 事件类型
  • matcher
  • 命令内容
  • 来自哪个 settings.json 文件

如果你的 Hook 没有出现在列表里,说明配置没有被正确加载(通常是 JSON 格式错误或文件路径问题)。


用 stderr 输出调试信息

Hook 脚本输出到 stderr 的内容,Claude Code 会直接展示出来(和 AI 的对话一起显示)。

在脚本里加调试输出:

bash
#!/bin/bash

# 调试:打印收到的完整输入
INPUT=$(cat)
echo "DEBUG: received input: $INPUT" >&2

FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
echo "DEBUG: file_path = $FILE_PATH" >&2

# ... 实际逻辑

确认问题修复后删掉这些 echo 行。


Hook 超时

默认情况下,如果 Hook 脚本运行超过 60 秒,Claude Code 会超时并继续执行(不会等 Hook 完成)。

如果你的 Hook 需要更长时间(比如调用一个慢速的外部 API),考虑改成异步模式——让脚本后台执行,立刻返回:

bash
#!/bin/bash

# 后台执行慢速操作,立刻返回
{
  # 这里是慢速操作
  curl -s "https://slow-api.example.com/notify" > /dev/null 2>&1
} &

exit 0   # 立刻返回,不等后台任务

手动测试 Hook 脚本

不用在 Claude Code 里触发,可以直接在终端手动测试脚本:

bash
# 模拟 PreToolUse 的输入,测试文件保护脚本
echo '{"tool_name": "Edit", "tool_input": {"file_path": "/project/.env"}}' \
  | .claude/hooks/protect-files.sh

echo "Exit code: $?"   # 应该是 2(被阻止)
bash
# 测试放行的情况
echo '{"tool_name": "Edit", "tool_input": {"file_path": "/project/src/app.ts"}}' \
  | .claude/hooks/protect-files.sh

echo "Exit code: $?"   # 应该是 0(放行)

这样可以在不启动 Claude Code 的情况下,快速验证脚本逻辑是否正确。


一个检查清单

Hook 不工作时,按这个顺序排查:

□ 脚本文件有执行权限(chmod +x)
□ settings.json 是合法的 JSON(jq . 验证)
□ /hooks 命令里能看到这个 Hook
□ matcher 设置正确(临时改成 "" 测试)
□ jq 已安装(如果脚本用了 jq)
□ 手动测试脚本能正确执行(echo "..." | ./script.sh)
□ 脚本的 shebang 行正确(#!/bin/bash)
□ 脚本路径是绝对路径或用了 $CLAUDE_PROJECT_DIR

第八章小结

Hooks 是 Claude Code 里最"硬核"的部分,也是最可靠的部分:

  • 设计哲学:LLM 是概率性的,Hooks 提供确定性保障
  • 四个事件:Pre/PostToolUse 处理工具调用,Notification 发通知,SessionStart 恢复上下文
  • Exit code 2:PreToolUse 里用它阻止危险操作
  • stderr:给 Claude Code 解释为什么阻止,让它调整方案

从通知开始,一个一个加——每加一个都是对你工作流的一次加固。

下一章,最后一个主题:用 SDK 把 Claude Code 嵌进你的脚本和 CI/CD 流程。

基于 CC BY-NC-SA 4.0 协议发布