Hooks 改参数要守规矩:updatedInput 现在会被校验
Claude Code 的钩子不只能「放行 / 拦截」,还能改写工具参数:
PreToolUse钩子在hookSpecificOutput里返回updatedInput,替换工具即将使用的参数;PermissionRequest钩子在decision对象里返回updatedInput,在批准的同时改掉输入。
常见用法包括:给 npm test 自动加上 --silent、把危险路径改写到沙箱目录、替用户回答 AskUserQuestion 等。
CLI 2.1.300 收紧了这条通道:钩子返回的 updatedInput 现在会像 Claude 自己生成的输入一样被校验。
具体变了什么
按更新日志,新规则有两条:
- 未知字段会被丢弃:你在
updatedInput里多塞的、工具 schema 里没有的键,直接去掉,不会传给工具; - 工具不接受的输入会拒绝这次调用:类型不对、缺必填项、值不合法,这次工具调用会被拒绝,而不是带着坏参数硬跑。
以前钩子的改写在一定程度上是「你写什么就用什么」,现在多了一道和 Claude 输入同等级别的检查。
为什么要这样
- 少一种隐蔽失败:钩子拼错字段名(比如把
command写成cmd),以前可能导致工具拿到奇怪的输入、行为难以预料; - 不给工具塞私货:多余字段被丢弃,避免钩子无意中把调试信息、内部标记带进工具调用;
- 失败时偏向安全:非法输入直接拒绝,而不是放过一个形状不对的调用。这和 2.1.295 的 onFailure: "block" 思路一致——钩子出问题时宁可拦住。
钩子作者要自查的几点
1. updatedInput 是整体替换,别只写改动的字段
官方文档一直强调:updatedInput 会替换整个输入对象,没改的字段也要原样带上。以前漏写字段也许还能凑合跑,现在如果漏掉的是必填项,调用会被直接拒绝。
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"updatedInput": {
"command": "npm test -- --silent",
"description": "Run tests quietly"
}
}
}更稳妥的写法是:读入原始 tool_input,在它上面修改,再整体返回。比如用 jq:
#!/usr/bin/env bash
input=$(cat)
echo "$input" | jq '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "allow",
updatedInput: (.tool_input + { command: (.tool_input.command + " --silent") })
}
}'2. 字段名和类型对照工具定义
不确定某个工具接受哪些参数,可以在 --debug 日志或会话记录里看 Claude 正常调用时传的输入,照着结构改。数字就给数字,布尔就给布尔,不要都写成字符串。
3. 别再靠自定义字段传「暗号」
如果你之前在 updatedInput 里加了自定义键,指望下游的另一个钩子或 MCP 工具读到——现在这些键会被丢掉。需要传递额外信息,考虑用 additionalContext 告诉 Claude,或者在钩子自己的状态文件里记录。
4. 修改后的输入仍然要过权限规则
文档写明,Claude Code 会用钩子返回的输入去评估权限规则(以及 Bash 命令能否自动转后台),而不是 Claude 原本发的那份。所以改写成一个被 deny 规则命中的命令,照样会被拒绝;PermissionRequest 里返回的 updatedInput 也会重新对照 deny 和 ask 规则。
同版本相关改动
2.1.300 还调整了一处钩子行为:在 Cowork 云端会话里,PermissionRequest 钩子批准时附带的 setMode(切换权限模式)会被忽略,其余批准内容照常生效。本地终端用户不受影响。
升级后怎么验证
claude --version确认 ≥ 2.1.300;- 用
claude --debug跑一遍会触发你钩子的操作,看工具是否按预期执行; - 如果某个原本能用的改写开始被拒,优先检查:是否漏了必填字段、字段名拼写、值的类型。
小结
- 2.1.300 起,
PreToolUse和PermissionRequest钩子的updatedInput按工具自身的规则校验; - 未知字段被丢弃,非法输入直接拒绝调用;
- 写钩子时在原始
tool_input基础上修改并整体返回,最不容易出错。