ECC Hook 修复 — 2026-04-21¶
摘要¶
Windows 上的 Claude Code CLI v2.1.116 所有 Bash 工具 Hook 调用均失败,报错:
PreToolUse:Bash hook error
Failed with non-blocking status code:
C:\Program Files\Git\bin\bash.exe: C:\Program Files\Git\bin\bash.exe:
cannot execute binary file
PostToolUse:Bash hook error (同上)
结果:observations.jsonl 在 2026-04-20T23:03:38Z 之后停止更新(最后一条记录是之前 stdin 带 BOM 问题导致的 parse_error)。
根本原因¶
C:\Users\sugig\.claude\settings.local.json 存在两个缺陷:
缺陷 1 — UTF-8 BOM + CRLF 行尾¶
文件以 EF BB BF(UTF-8 BOM)开头,并使用 CRLF 行结束符。
这是 PowerShell ConvertTo-Json | Out-File 的默认行为,也是
patch_settings_cl_v2_simple.ps1 重写文件后留下的结果。
缺陷 2 — 双重包装的 bash.exe 调用¶
命令字符串显式再次调用了 bash.exe:
"command": "\"C:\\Program Files\\Git\\bin\\bash.exe\" \"C:\\Users\\sugig\\.claude\\skills\\continuous-learning\\hooks\\observe-wrapper.sh\""
当 Claude Code 在 Windows 上启动该命令时,参数拆分无法正确保留
带引号的 "C:\Program Files\..." 标记。Program Files 中的空格会拆分
argv[0],导致 bash.exe 最终把自己当作脚本文件传入,产生:
之前可用的形态(供参考)¶
在 patch_settings_cl_v2_simple.ps1 运行之前,命令只是:
Windows 上的 Claude Code 会检测 .sh 并通过 Git Bash 本身调用它——无需
手动包装 bash.exe。
修复¶
C:\Users\sugig\.claude\settings.local.json 已重写为 UTF-8(无 BOM)、LF
行尾,命令直接指向包装器 .sh,并将 Hook 阶段作为普通参数传入:
{
"hooks": {
"PreToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh pre"
}
]
}
],
"PostToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh post"
}
]
}
]
}
}
附带好处:pre / post 参数现在会路由到 observe.sh 的
HOOK_PHASE 变量,因此事件会被正确记录为 tool_start 或
tool_complete(之前所有事件都被记录为 tool_complete)。
验证¶
直接调用新命令格式,模拟两个 Hook 阶段:
# PostToolUse path
echo '{"tool_name":"Bash","tool_input":{"command":"pwd"},"session_id":"post-fix-verify-001","cwd":"...","hook_event_name":"PostToolUse"}' \
| "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh" post
# exit=0
# PreToolUse path
echo '{"tool_name":"Bash","tool_input":{"command":"ls"},"session_id":"post-fix-verify-pre-001","cwd":"...","hook_event_name":"PreToolUse"}' \
| "C:/Users/sugig/.claude/skills/continuous-learning/hooks/observe-wrapper.sh" pre
# exit=0
observations.jsonl 新增:
{"timestamp":"2026-04-21T05:57:54Z","event":"tool_complete","tool":"Bash","session":"post-fix-verify-001",...}
{"timestamp":"2026-04-21T05:57:55Z","event":"tool_start","tool":"Bash","session":"post-fix-verify-pre-001","input":"{\"command\":\"ls\"}",...}
两个阶段现在都会生成类型正确的事件。
关于实时 CLI 验证的说明: 设置更改会在下一次
claude CLI 会话启动时生效。重启 CLI 并运行一次 Bash 工具调用,以确认
实际 CLI 会话在 observations.jsonl 中出现新行。
涉及文件¶
C:\Users\sugig\.claude\settings.local.json— 已重写C:\Users\sugig\.claude\settings.local.json.bak-hookfix-20260421-145718— 修复前备份
已知上游 Bug(此处未修复)¶
install_hook_wrapper.ps1— 在步骤 [3/4] 处停止,从未到达 [4/4]。patch_settings_cl_v2_simple.ps1— 会用 UTF-8-BOM + CRLF 覆盖settings.local.json,并重新引入双重包装的bash.exe命令。 应替换为输出 UTF-8(无 BOM)、LF 和直接.sh路径的补丁程序。
分支¶
claude/hook-fix-20260421
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC