6
0

Claude Code 插件路径带空格导致 hook 启动失败的踩坑记录

2026-06-24
2026-06-24
Claude Code 插件路径带空格导致 hook 启动失败的踩坑记录

问题现象

如果在 Windows 上使用 Claude Code 时修改了 CLAUDE_CONFIG_DIR 环境变量到一个有空格的目录下,启动某些插件(如 Warp 的 claude code 插件)时,可能会报:

SessionStart:startup hook error
Failed with non-blocking status code:
bash: <path-before-space>: No such file or directory

典型表现是路径里有空格,例如:

<DRIVE>:\<some folder with space>\.claude\plugins\...

bash 报错只截到了空格前半段,例如:

bash: <DRIVE>:/some/folder: No such file or directory

这说明 hook command 在执行时没有正确处理带空格路径。

根因:hook 命令直接拼了插件根目录

原始 hooks.json 里类似这样:

"command": "${CLAUDE_PLUGIN_ROOT}/scripts/on-session-start.sh"

${CLAUDE_PLUGIN_ROOT} 展开后包含空格,执行层可能把路径拆成多个参数,导致 bash 只看到空格前半段。

修复方式是不要直接执行绝对路径,而是先进入插件目录,再用相对路径执行脚本:

"command": "cd \"${CLAUDE_PLUGIN_ROOT}\" && bash ./scripts/on-session-start.sh"

其它 hook 也同理,例如:

"command": "cd \"${CLAUDE_PLUGIN_ROOT}\" && bash ./scripts/on-stop.sh"

核心思路:

cd "${CLAUDE_PLUGIN_ROOT}" && bash ./scripts/xxx.sh

这样只有 cd 需要处理带空格路径,脚本路径本身变成无空格的相对路径。

坑1:Claude Code 实际读取的是插件缓存

一开始只改了 marketplace 源目录下的插件配置,例如:

<CLAUDE_HOME>\plugins\marketplaces\<marketplace-name>\plugins\<plugin-name>\hooks\hooks.json

但 Claude Code 启动时实际使用的是缓存目录里的副本:

<CLAUDE_HOME>\plugins\cache\<marketplace-name>\<plugin-name>\<version>\hooks\hooks.json

所以必须同步修改缓存里的 hooks.json。否则即使源目录改对了,启动时仍然会继续报旧错误。

坑2:Windows PowerShell 写 JSON 可能带 BOM

修改完缓存配置后,又遇到:

Failed to load hooks from ...hooks.json:
JSON Parse error: Unrecognized token ''

这是因为用 PowerShell 写文件时,可能把 JSON 保存成了带 BOM 的 UTF-8。某些 JSON parser 不接受开头的 BOM 隐藏字符。

解决方式:确保 hooks.jsonUTF-8 without BOM

PowerShell 可用这种方式写入无 BOM:

$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
[System.IO.File]::WriteAllText($path, $text, $utf8NoBom)

确认文件开头应直接是 {,前三字节类似:

7B 0D 0A

而不是 UTF-8 BOM:

EF BB BF

最终修复方案

需要同步修改两处 hooks.json

<CLAUDE_HOME>\plugins\marketplaces\<marketplace-name>\plugins\<plugin-name>\hooks\hooks.json
<CLAUDE_HOME>\plugins\cache\<marketplace-name>\<plugin-name>\<version>\hooks\hooks.json

将所有类似:

"command": "${CLAUDE_PLUGIN_ROOT}/scripts/on-session-start.sh"

改为:

"command": "cd \"${CLAUDE_PLUGIN_ROOT}\" && bash ./scripts/on-session-start.sh"

并确保文件编码为:

UTF-8 without BOM

经验总结

  • Windows 路径里有空格时,hook command 必须显式引用变量。
  • 插件源目录改了不一定生效,Claude Code 可能使用 cache 副本。
  • 修改 JSON 配置后,注意不要写入 UTF-8 BOM。
  • 对 shell hook 来说,cd "$ROOT" && bash ./relative-script.sh 通常比直接执行绝对路径更稳。

评论