10 10
11## 找出为什么 mod 不起作用11## 找出为什么 mod 不起作用
12 12
13当 mod 不起作用时,请检查 Claude Code 从 mod 文件读取的内容,以及它在跳过某些内容时写入的行。对于第一项,在您的 shell 中运行 [`claude plugin validate`](/docs/zh-CN/plugins/mods/create#check-what-claude-code-reads-from-your-mod),使用 mod 的目录,如 `claude plugin validate ./first-mod`。它可以捕获拼写错误的事件、错误的清单和 Claude Code 无法读取的模块,而无需启动会话。13当 mod 不起作用时,请检查 Claude Code 从 mod 文件读取的内容,以及它在跳过某些内容时写入的行。对于第一项,在您的 shell 中运行 [`claude plugin validate`](https://code.claude.com/docs/zh-CN/plugins/mods/create#check-what-claude-code-reads-from-your-mod),使用 mod 的目录,如 `claude plugin validate ./first-mod`。它可以捕获拼写错误的事件、错误的清单和 Claude Code 无法读取的模块,而无需启动会话。
14 14
15当模块未加载、hook 被跳过或另一个 mod 拒绝您的 mod 时,Claude Code 会写入一行,其中命名您的 mod。您读取该行的位置取决于会话:15当模块未加载、hook 被跳过或另一个 mod 拒绝您的 mod 时,Claude Code 会写入一行,其中命名您的 mod。您读取该行的位置取决于会话:
16 16
17* **热重新加载插件目录的会话**:成绩单中的暗行。这是您使用 `--plugin-dir` 启动的交互式会话,或者是您为 Claude 编写的 mod [启用热重新加载](/docs/zh-CN/plugins/mods/create.md#ask-claude-for-a-mod) 的会话。17* **热重新加载插件目录的会话**:成绩单中的暗行。这是您使用 `--plugin-dir` 启动的交互式会话,或者是您为 Claude 编写的 mod [启用热重新加载](https://code.claude.com/docs/zh-CN/plugins/mods/create.md#ask-claude-for-a-mod) 的会话。
18* **任何其他交互式会话,例如运行您从市场安装的 mod 的会话**:[调试日志](#read-the-debug-log) 仅。要获取一个,请使用 `claude --debug` 启动会话。18* **任何其他交互式会话,例如运行您从市场安装的 mod 的会话**:[调试日志](#read-the-debug-log) 仅。要获取一个,请使用 `claude --debug` 启动会话。
19* **带有 `--plugin-dir` 的 `claude -p` 运行**:stderr,采用默认文本输出格式。另一个 mod 的拒绝仅进入调试日志。19* **带有 `--plugin-dir` 的 `claude -p` 运行**:stderr,采用默认文本输出格式。另一个 mod 的拒绝仅进入调试日志。
20 20
29| `hooks modules are turned off in this process: the rollout switch served off` | Anthropic 已远程关闭已安装的 mod。 |29| `hooks modules are turned off in this process: the rollout switch served off` | Anthropic 已远程关闭已安装的 mod。 |
30| `hooks modules are turned off in this process: the rollout switch was saved off by an earlier session` | 该命令使用了之前某个会话保存的值,该值可能已过时。请启动一次 `claude` 以刷新该值,然后再次运行该命令。 |30| `hooks modules are turned off in this process: the rollout switch was saved off by an earlier session` | 该命令使用了之前某个会话保存的值,该值可能已过时。请启动一次 `claude` 以刷新该值,然后再次运行该命令。 |
31 31
32组织还可以设置 `allowManagedModsOnly` 以仅允许其自己的 mod,此命令不会报告。在这种情况下,Claude Code 会拒绝您安装的 mod,并且[会有消息说明原因](/docs/zh-CN/plugins/mods/troubleshoot.md#messages-from-the-built-in-guard)。32组织还可以设置 `allowManagedModsOnly` 以仅允许其自己的 mod,此命令不会报告。在这种情况下,Claude Code 会拒绝您安装的 mod,并且[会有消息说明原因](https://code.claude.com/docs/zh-CN/plugins/mods/troubleshoot.md#messages-from-the-built-in-guard)。
33 33
34## mod 不加载34## mod 不加载
35 35
37 37
38### 您的版本过旧38### 您的版本过旧
39 39
40请参阅[应使用哪个版本以及如何检查您的版本](/docs/zh-CN/plugins/mods/overview.md#turn-mods-on-or-off)。40请参阅[应使用哪个版本以及如何检查您的版本](https://code.claude.com/docs/zh-CN/plugins/mods/overview.md#turn-mods-on-or-off)。
41 41
42### `mods active` 行不命名 mod42### `mods active` 行不命名 mod
43 43
44mod 添加的任何内容都不会出现,`/plugin` 中的 [`mods active` 行](/docs/zh-CN/plugins/mods/overview#see-which-mods-a-session-loaded) 不命名它。hooks 模块未加载。当 Claude Code 拒绝它时,调试日志有一行以 `hooks module`、mod 的名称和 `not loaded:` 开头,如 `hooks module first-mod@inline not loaded: disableAllHooks in managed settings`,用于使用 `--plugin-dir` 加载的 mod。44mod 添加的任何内容都不会出现,`/plugin` 中的 [`mods active` 行](https://code.claude.com/docs/zh-CN/plugins/mods/overview#see-which-mods-a-session-loaded) 不命名它。hooks 模块未加载。当 Claude Code 拒绝它时,调试日志有一行以 `hooks module`、mod 的名称和 `not loaded:` 开头,如 `hooks module first-mod@inline not loaded: disableAllHooks in managed settings`,用于使用 `--plugin-dir` 加载的 mod。
45 45
46读取冒号后的原因。[拒绝消息](#refusal-messages) 部分列出了每一个。如果日志中没有这样的行,请逐一处理此组中的其他条目。46读取冒号后的原因。[拒绝消息](#refusal-messages) 部分列出了每一个。如果日志中没有这样的行,请逐一处理此组中的其他条目。
47 47
48某些设置会阻止 mod,同时让其插件的其余部分继续工作。[启用或关闭 mod](/docs/zh-CN/plugins/mods/overview.md#turn-mods-on-or-off) 列出了这些设置。48某些设置会阻止 mod,同时让其插件的其余部分继续工作。[启用或关闭 mod](https://code.claude.com/docs/zh-CN/plugins/mods/overview.md#turn-mods-on-or-off) 列出了这些设置。
49 49
50### `claude -p` 运行打印 `hooks module not loaded`50### `claude -p` 运行打印 `hooks module not loaded`
51 51
64| `disableAllHooks in managed settings` | 您的组织关闭了来自已安装插件的 hooks |64| `disableAllHooks in managed settings` | 您的组织关闭了来自已安装插件的 hooks |
65| `only managed plugins and built-in plugins run` | 设置了 `allowManagedHooksOnly`,或在托管设置以外的设置文件中设置了 `disableAllHooks` |65| `only managed plugins and built-in plugins run` | 设置了 `allowManagedHooksOnly`,或在托管设置以外的设置文件中设置了 `disableAllHooks` |
66| `installed plugins that are not managed load no hooks module in this mode (--bare)` | 您使用 `--bare` 启动了 Claude Code |66| `installed plugins that are not managed load no hooks module in this mode (--bare)` | 您使用 `--bare` 启动了 Claude Code |
67| `another plugin of that name loads first` | 另一个已启用的插件与您的 mod 同名,并且[占用了该名称](/docs/zh-CN/plugins/loading.md#hooks-when-two-enabled-plugins-share-a-name),因此您的 hook 模块不会加载 |67| `another plugin of that name loads first` | 另一个已启用的插件与您的 mod 同名,并且[占用了该名称](https://code.claude.com/docs/zh-CN/plugins/loading.md#hooks-when-two-enabled-plugins-share-a-name),因此您的 hook 模块不会加载 |
68 68
69### 来自内置保护的消息69### 来自内置保护的消息
70 70
71在具有托管设置的机器上,或在凭据为 Team 或 Enterprise `/login` 的会话中,[内置守卫](/docs/zh-CN/plugins/mods/admin.md#know-what-happens-by-default) 可以拒绝 mod 或其答案之一。每条消息都会指明您的组织管理员为更改该规则而设置的选项。71在具有托管设置的机器上,或在凭据为 Team 或 Enterprise `/login` 的会话中,[内置守卫](https://code.claude.com/docs/zh-CN/plugins/mods/admin.md#know-what-happens-by-default) 可以拒绝 mod 或其答案之一。每条消息都会指明您的组织管理员为更改该规则而设置的选项。
72 72
73| 消息包含 | 这意味着什么 | 它出现在哪里 |73| 消息包含 | 这意味着什么 | 它出现在哪里 |
74| :- | :- | :- |74| :- | :- | :- |
75| `mods are limited to your organization's by policy (allowManagedModsOnly)` | 您的组织仅允许 [其自己的 mod](/docs/zh-CN/plugins/mods/admin.md#install-your-organizations-mods),因此您的 mod 被拒绝 | 调试日志,以及 [热重新加载插件目录的会话](#find-out-why-a-mod-does-nothing) 中的会话记录 |75| `mods are limited to your organization's by policy (allowManagedModsOnly)` | 您的组织仅允许 [其自己的 mod](https://code.claude.com/docs/zh-CN/plugins/mods/admin.md#install-your-organizations-mods),因此您的 mod 被拒绝 | 调试日志,以及 [热重新加载插件目录的会话](#find-out-why-a-mod-does-nothing) 中的会话记录 |
76| `tried to lift a deny rule in your settings` | 您的 mod 的 [`tool.check`](/docs/zh-CN/plugins/mods/reference#tools) hook 批准了 `deny` 规则拒绝的调用。该调用保持被拒绝。 | 成绩单和调试日志,会话中每个 mod 一次。在 `claude -p` 运行中,仅调试日志。 |76| `tried to lift a deny rule in your settings` | 您的 mod 的 [`tool.check`](https://code.claude.com/docs/zh-CN/plugins/mods/reference#tools) hook 批准了 `deny` 规则拒绝的调用。该调用保持被拒绝。 | 成绩单和调试日志,会话中每个 mod 一次。在 `claude -p` 运行中,仅调试日志。 |
77| `the deny rules in your settings could not be checked for this call, so it is refused` | 保护在检查 mod 批准的调用时失败,因此它拒绝了该调用 | Claude 为被拒绝的调用读取的原因 |77| `the deny rules in your settings could not be checked for this call, so it is refused` | 保护在检查 mod 批准的调用时失败,因此它拒绝了该调用 | Claude 为被拒绝的调用读取的原因 |
78 78
79### `validate` 通过且不列出 `hooks` 行79### `validate` 通过且不列出 `hooks` 行
88 88
89修复原因命名的错误。89修复原因命名的错误。
90 90
91如果原因以 `; the version loaded before is unloaded` 结尾,则该 mod 当前没有任何版本在运行。修复错误后,在会话中运行 [`/reload-plugins`](/docs/zh-CN/plugins/cli-reference#reload-plugins) 以再次加载该 mod。如果该 mod 是您安装的而非您编写的,请让其作者修复该错误。91如果原因以 `; the version loaded before is unloaded` 结尾,则该 mod 当前没有任何版本在运行。修复错误后,在会话中运行 [`/reload-plugins`](https://code.claude.com/docs/zh-CN/plugins/cli-reference#reload-plugins) 以再次加载该 mod。如果该 mod 是您安装的而非您编写的,请让其作者修复该错误。
92 92
93### `options do not fit plugin.json userConfig`93### `options do not fit plugin.json userConfig`
94 94
95该行以 mod 的名称开头,然后是 `hooks module did not load: options do not fit plugin.json userConfig:` 和一个原因。某个选项未通过其 [`userConfig`](/docs/zh-CN/plugins/components#user-configuration) 字段的验证,例如高于字段 `max` 的数字,或必需字段没有值。95该行以 mod 的名称开头,然后是 `hooks module did not load: options do not fit plugin.json userConfig:` 和一个原因。某个选项未通过其 [`userConfig`](https://code.claude.com/docs/zh-CN/plugins/components#user-configuration) 字段的验证,例如高于字段 `max` 的数字,或必需字段没有值。
96 96
97设置或更改值。该行的末尾命名其在 `settings.json` 中的 `pluginConfigs` 条目。97设置或更改值。该行的末尾命名其在 `settings.json` 中的 `pluginConfigs` 条目。
98 98
99### `code nested too deep to scan: more than 2000 scopes`99### `code nested too deep to scan: more than 2000 scopes`
100 100
101该行以 mod 的名称开头,然后是 `hooks module did not load:`、文件,以及 `code nested too deep to scan: more than 2000 scopes`。hook 模块中的文件不能将作用域(例如函数、块和循环)嵌套超过 [2,000 层](/docs/zh-CN/plugins/mods/reference.md#limits)。[`claude plugin validate`](/docs/zh-CN/plugins/mods/create#check-what-claude-code-reads-from-your-mod) 会报告相同的原因。101该行以 mod 的名称开头,然后是 `hooks module did not load:`、文件,以及 `code nested too deep to scan: more than 2000 scopes`。hook 模块中的文件不能将作用域(例如函数、块和循环)嵌套超过 [2,000 层](https://code.claude.com/docs/zh-CN/plugins/mods/reference.md#limits)。[`claude plugin validate`](https://code.claude.com/docs/zh-CN/plugins/mods/create#check-what-claude-code-reads-from-your-mod) 会报告相同的原因。
102 102
103重写代码,减少其作用域的嵌套深度。103重写代码,减少其作用域的嵌套深度。
104 104
105### `the engine ran out of stack linking the file and its imports`
106
107hook 模块中的代码嵌套过深,或其导入链过长,导致 Claude Code 无法加载它。该行以 mod 的名称和 `hooks module did not load:` 开头,然后给出某个文件的名称以及此原因。
108
109请在该文件以及通过其导入所到达的文件中查找嵌套最深的部分,并重写该部分以减少嵌套,或缩短导入链。如果该 mod 是您安装的而非您编写的,请让其作者进行修改。
110
105### `the parser stopped` 或 `the engine ran out of stack loading the file`111### `the parser stopped` 或 `the engine ran out of stack loading the file`
106 112
107hook 模块某个文件中的代码嵌套过深,导致 Claude Code 在读取时耗尽了栈空间。该行以 mod 的名称和 `hooks module did not load:` 开头,然后给出该文件的名称以及以下原因之一:113hook 模块某个文件中的代码嵌套过深,导致 Claude Code 在读取时耗尽了栈空间。该行以 mod 的名称和 `hooks module did not load:` 开头,然后给出该文件的名称以及以下原因之一:
125 131
126### Claude Code 不再询问是否启用热重载132### Claude Code 不再询问是否启用热重载
127 133
128Claude 在交互式会话中编写了 mod,但没有任何内容加载,而且 Claude Code 不再询问[是否启用热重载](/docs/zh-CN/plugins/mods/create.md#ask-claude-for-a-mod)。如果该问题有三次在未选择任何答案的情况下结束,热重载将保持关闭。例如,当您设置了 [`askUserQuestionTimeout`](/docs/zh-CN/settings-reference#askuserquestiontimeout) 并且在您回答之前时间已到时,问题就会以这种方式结束。该设置在此适用,是因为 Claude Code 使用与 [`AskUserQuestion` 相同的问题对话框](/docs/zh-CN/tools-reference#question-auto-continue-timeout)进行询问。您自己关闭的问题不计入这三次。134Claude 在交互式会话中编写了 mod,但没有任何内容加载,而且 Claude Code 不再询问[是否启用热重载](https://code.claude.com/docs/zh-CN/plugins/mods/create.md#ask-claude-for-a-mod)。如果该问题有三次在未选择任何答案的情况下结束,热重载将保持关闭。例如,当您设置了 [`askUserQuestionTimeout`](https://code.claude.com/docs/zh-CN/settings-reference#askuserquestiontimeout) 并且在您回答之前时间已到时,问题就会以这种方式结束。该设置在此适用,是因为 Claude Code 使用与 [`AskUserQuestion` 相同的问题对话框](https://code.claude.com/docs/zh-CN/tools-reference#question-auto-continue-timeout)进行询问。您自己关闭的问题不计入这三次。
129 135
130要运行该 mod,请[将其目录从 mods 文件夹中复制出来](/docs/zh-CN/plugins/mods/create.md#use-the-mod-in-other-sessions),然后在 shell 中使用 `--plugin-dir` 启动新会话,例如 `claude --plugin-dir ~/mods/git-branch`。136要运行该 mod,请[将其目录从 mods 文件夹中复制出来](https://code.claude.com/docs/zh-CN/plugins/mods/create.md#use-the-mod-in-other-sessions),然后在 shell 中使用 `--plugin-dir` 启动新会话,例如 `claude --plugin-dir ~/mods/git-branch`。
131 137
132## hook 被跳过或 mod 被卸载138## hook 被跳过或 mod 被卸载
133 139
135 141
136### `hook skipped`142### `hook skipped`
137 143
138该行命名 mod 和事件,然后说 `hook skipped:` 和一个原因,如 `first-mod: tool.call hook skipped: threw Error: boom`。hook 抛出了异常、运行超过了其[时间限制](/docs/zh-CN/plugins/mods/reference.md#limits),或返回了错误形状的结果。该行对每个事件和失败类型出现一次,直到 mod 重新加载。144该行命名 mod 和事件,然后说 `hook skipped:` 和一个原因,如 `first-mod: tool.call hook skipped: threw Error: boom`。hook 抛出了异常、运行超过了其[时间限制](https://code.claude.com/docs/zh-CN/plugins/mods/reference.md#limits),或返回了错误形状的结果。该行对每个事件和失败类型出现一次,直到 mod 重新加载。
139 145
140修复错误。调试日志对每次出现都有一行。146修复错误。调试日志对每次出现都有一行。
141 147
143 149
144您运行了 mod 添加的命令,回复命名了 mod 和命令,如 `first-mod registered /tally but no command.run hook answered it`,然后告诉您添加一个 hook。当命令到达链的末尾而没有答案时,Claude Code 会打印该回复,这发生在两种情况下:150您运行了 mod 添加的命令,回复命名了 mod 和命令,如 `first-mod registered /tally but no command.run hook answered it`,然后告诉您添加一个 hook。当命令到达链的末尾而没有答案时,Claude Code 会打印该回复,这发生在两种情况下:
145 151
146* **没有 hook 回答命令**:模块没有 `command.run` hook,hook 的 [filter](/docs/zh-CN/plugins/mods/events.md#filter-which-events-a-hook-handles) 命名了不同的命令,或 hook 返回了 `next(e)`152* **没有 hook 回答命令**:模块没有 `command.run` hook,hook 的 [filter](https://code.claude.com/docs/zh-CN/plugins/mods/events.md#filter-which-events-a-hook-handles) 命名了不同的命令,或 hook 返回了 `next(e)`
147* **Claude Code 跳过了 hook**:[`hook skipped`](#hook-skipped) 列出了原因。将 `focus: false` 传递给 [`$.ui.open`](/docs/zh-CN/plugins/mods/interface#open-a-pane-at-the-right-time) 是到达那里的一种方式。153* **Claude Code 跳过了 hook**:[`hook skipped`](#hook-skipped) 列出了原因。将 `focus: false` 传递给 [`$.ui.open`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#open-a-pane-at-the-right-time) 是到达那里的一种方式。
148 154
149如果模块已经有回复描述的 hook,请查找命名 `command.run` 的 `hook skipped` 行,它给出了原因。运行命令的 [test](/docs/zh-CN/plugins/mods/test.md) 失败,原因相同。155如果模块已经有回复描述的 hook,请查找命名 `command.run` 的 `hook skipped` 行,它给出了原因。运行命令的 [test](https://code.claude.com/docs/zh-CN/plugins/mods/test.md) 失败,原因相同。
150 156
151### `it crashed the hooks worker`157### `it crashed the hooks worker`
152 158
156 162
157### `its session.start ran again in a fresh copy`163### `its session.start ran again in a fresh copy`
158 164
159该行以 mod 的名称开头,并指出一个 `$.prompt.submit`、`$.command.run` 或 `$.agent.spawn` 调用,如 `first-mod: its session.start ran again in a fresh copy; the $.prompt.submit call it had already made was not made again`。Claude Code 再次加载了该 mod 的模块(例如在 hooks worker 崩溃并被替换之后),新副本的 [`session.start`](/docs/zh-CN/plugins/mods/reference#session) hook 运行了。该行指出的调用以其首次运行的结果完成,而没有再次运行,因此您的 mod 不会重复提交提示词、运行命令或启动子代理。hook 的其余部分照常运行。165该行以 mod 的名称开头,并指出一个 `$.prompt.submit`、`$.command.run` 或 `$.agent.spawn` 调用,如 `first-mod: its session.start ran again in a fresh copy; the $.prompt.submit call it had already made was not made again`。Claude Code 再次加载了该 mod 的模块(例如在 hooks worker 崩溃并被替换之后),新副本的 [`session.start`](https://code.claude.com/docs/zh-CN/plugins/mods/reference#session) hook 运行了。该行指出的调用以其首次运行的结果完成,而没有再次运行,因此您的 mod 不会重复提交提示词、运行命令或启动子代理。hook 的其余部分照常运行。
160 166
161无需修复。167无需修复。
162 168
166 172
167该行以您的 mod 名称开头,如 `first-mod: $.agent.register refused: the hooks module that made the call is no longer loaded (it was reloaded or removed)`,且该 Agent 未被注册。您的 mod 在该调用之前被重新加载或卸载。重新加载会加载 hook 模块的新副本,而此调用来自仍在旧副本中运行的代码,例如尚未返回的 hook。173该行以您的 mod 名称开头,如 `first-mod: $.agent.register refused: the hooks module that made the call is no longer loaded (it was reloaded or removed)`,且该 Agent 未被注册。您的 mod 在该调用之前被重新加载或卸载。重新加载会加载 hook 模块的新副本,而此调用来自仍在旧副本中运行的代码,例如尚未返回的 hook。
168 174
169如果该 hook 未捕获此拒绝,它会失败,Claude Code 会[跳过它](#hook-skipped)。要从保持加载的副本注册该 Agent,请在您的 [`session.start`](/docs/zh-CN/plugins/mods/reference#session) hook 中进行该调用,该 hook 会在重新加载后的每个新副本中再次运行。175如果该 hook 未捕获此拒绝,它会失败,Claude Code 会[跳过它](#hook-skipped)。要从保持加载的副本注册该 Agent,请在您的 [`session.start`](https://code.claude.com/docs/zh-CN/plugins/mods/reference#session) hook 中进行该调用,该 hook 会在重新加载后的每个新副本中再次运行。
170 176
171### `mods that run in the hooks worker are off for this session`177### `mods that run in the hooks worker are off for this session`
172 178
180 186
181### `a hook changed this call's input after the model wrote it`187### `a hook changed this call's input after the model wrote it`
182 188
183在自动模式下,被拒绝的工具调用给出此原因。hook 在 [服务器端分类器](/docs/zh-CN/permission-modes.md#server-side-classifier-review) 审查后更改了工具调用的输入,因此该审查不涵盖将运行的内容。hook 可以是 mod 的 [`tool.call`](/docs/zh-CN/plugins/mods/reference#tools) 或 [`turn.step`](/docs/zh-CN/plugins/mods/reference#turns) hook,或 [`PreToolUse`](/docs/zh-CN/hooks#pretooluse) 设置 hook。消息不说明是哪一个。189在自动模式下,被拒绝的工具调用给出此原因。hook 在 [服务器端分类器](https://code.claude.com/docs/zh-CN/permission-modes.md#server-side-classifier-review) 审查后更改了工具调用的输入,因此该审查不涵盖将运行的内容。hook 可以是 mod 的 [`tool.call`](https://code.claude.com/docs/zh-CN/plugins/mods/reference#tools) 或 [`turn.step`](https://code.claude.com/docs/zh-CN/plugins/mods/reference#turns) hook,或 [`PreToolUse`](https://code.claude.com/docs/zh-CN/hooks#pretooluse) 设置 hook。消息不说明是哪一个。
184 190
185消息告诉 Claude 再次发出记录的调用。如果也被拒绝,hook 每次都更改输入,因此关闭 mod 或 hook,或离开自动模式并自己批准调用。191消息告诉 Claude 再次发出记录的调用。如果也被拒绝,hook 每次都更改输入,因此关闭 mod 或 hook,或离开自动模式并自己批准调用。
186 192
194 200
195### `Stopped: type a message to continue; a mod cannot resume work after Stop`201### `Stopped: type a message to continue; a mod cannot resume work after Stop`
196 202
197此提示表示,在您停止轮次之后(例如按下 Esc),某个 mod 试图自行开始工作,而 Claude Code 没有允许它这样做。无需进行任何修复。在您发送下一条消息后,mod 可以再次开始工作,并且[其中部分工作会自行恢复](/docs/zh-CN/plugins/mods/api.md#work-your-mod-started-before-the-interruption)。如果您期望从该 mod 获得的结果没有恢复,请再次提出请求,或再次运行该 mod 的命令。203此提示表示,在您停止轮次之后(例如按下 Esc),某个 mod 试图自行开始工作,而 Claude Code 没有允许它这样做。无需进行任何修复。在您发送下一条消息后,mod 可以再次开始工作,并且[其中部分工作会自行恢复](https://code.claude.com/docs/zh-CN/plugins/mods/api.md#work-your-mod-started-before-the-interruption)。如果您期望从该 mod 获得的结果没有恢复,请再次提出请求,或再次运行该 mod 的命令。
198 204
199如果该 mod 是您编写的,请参阅[用户中断轮次后的调用和后台工作](/docs/zh-CN/plugins/mods/api.md#calls-and-background-work-after-the-user-interrupts-a-turn)。205如果该 mod 是您编写的,请参阅[用户中断轮次后的调用和后台工作](https://code.claude.com/docs/zh-CN/plugins/mods/api.md#calls-and-background-work-after-the-user-interrupts-a-turn)。
200 206
201## 绘图不出现或不响应207## 绘图不出现或不响应
202 208
204 210
205### 显示了另一个 mod 的带,而您的带没有显示211### 显示了另一个 mod 的带,而您的带没有显示
206 212
207输入框上方只有一个带,所有 mod 共用它。在[您的 mod 之前](/docs/zh-CN/plugins/mods/events.md#the-order-mods-run-in)运行的 mod 如果返回的树中不包含 `next(e)` 的结果,就会替换您的带。要同时显示两个带,请修改该 mod 的 hook,或请其作者修改:213输入框上方只有一个带,所有 mod 共用它。在[您的 mod 之前](https://code.claude.com/docs/zh-CN/plugins/mods/events.md#the-order-mods-run-in)运行的 mod 如果返回的树中不包含 `next(e)` 的结果,就会替换您的带。要同时显示两个带,请修改该 mod 的 hook,或请其作者修改:
208 214
209* **保留其后的带**:将 `await next(e)` 的结果放入其树中某个 `Box` 的子元素中,如[选择绘制位置](/docs/zh-CN/plugins/mods/interface.md#pick-where-to-draw)中“输入框上方的带”选项卡所示215* **保留其后的带**:将 `await next(e)` 的结果放入其树中某个 `Box` 的子元素中,如[选择绘制位置](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#pick-where-to-draw)中“输入框上方的带”选项卡所示
210* **保持树有效**:不要为该 `Box` 或其外层的任何 `Box` 设置 `width`、`height`、`minWidth`、`minHeight`、`position`、`top`、`left`、`right`、`bottom`、`display` 或 `overflow` prop216* **保持树有效**:不要为该 `Box` 或其外层的任何 `Box` 设置 `width`、`height`、`minWidth`、`minHeight`、`position`、`top`、`left`、`right`、`bottom`、`display` 或 `overflow` prop
211 217
212要找到该 mod,请[写入调试日志](#read-the-debug-log)并在其中搜索 `answered ui.render without next()`。诸如 `other-mod (user) answered ui.render without next()` 的行会指明一个返回了树但未调用 `next(e)` 的 mod。该行不会指明[渲染位置](/docs/zh-CN/plugins/mods/reference.md#render-sites),因此仅绘制窗格的 mod 也可能出现在其中。调用了 `next(e)` 但丢弃其结果的 mod 不会产生该行,因此也请检查在您的 mod 之前运行的 hook。218要找到该 mod,请[写入调试日志](#read-the-debug-log)并在其中搜索 `answered ui.render without next()`。诸如 `other-mod (user) answered ui.render without next()` 的行会指明一个返回了树但未调用 `next(e)` 的 mod。该行不会指明[渲染位置](https://code.claude.com/docs/zh-CN/plugins/mods/reference.md#render-sites),因此仅绘制窗格的 mod 也可能出现在其中。调用了 `next(e)` 但丢弃其结果的 mod 不会产生该行,因此也请检查在您的 mod 之前运行的 hook。
213 219
214进行更改后,如果任一 mod 返回的树未通过验证,带中将不显示任何内容。要了解原因,请在 `--plugin-dir` 会话的会话记录中查找 `ui.render (AbovePrompt) refused:` 行,或在调试日志中搜索 `does not validate`。当带中有多个 mod 时,这两行都不会指明具体的 mod,因此请检查每个 mod 的树。220进行更改后,如果任一 mod 返回的树未通过验证,带中将不显示任何内容。要了解原因,请在 `--plugin-dir` 会话的会话记录中查找 `ui.render (AbovePrompt) refused:` 行,或在调试日志中搜索 `does not validate`。当带中有多个 mod 时,这两行都不会指明具体的 mod,因此请检查每个 mod 的树。
215 221
216### 窗格或带为空或显示 Claude Code 的常规内容222### 窗格或带为空或显示 Claude Code 的常规内容
217 223
218您的 hook 返回的 [树](/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements) 未通过验证。使用 `--plugin-dir` 时,会话记录会显示 `ui.render (Pane) refused:` 及原因,如 `first-mod: ui.render (Pane) refused: Box prop "flexDirection" must be one of row, column, row-reverse, column-reverse; the engine drew its own`。调试日志中有 `a hook returned a tree that does not validate` 及相同的原因。224您的 hook 返回的 [树](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#build-a-tree-from-elements) 未通过验证。使用 `--plugin-dir` 时,会话记录会显示 `ui.render (Pane) refused:` 及原因,如 `first-mod: ui.render (Pane) refused: Box prop "flexDirection" must be one of row, column, row-reverse, column-reverse; the engine drew its own`。调试日志中有 `a hook returned a tree that does not validate` 及相同的原因。
219 225
220读取该行上的原因。常见原因是元素不接受的 prop 和应用没有的元素。226读取该行上的原因。常见原因是元素不接受的 prop 和应用没有的元素。
221 227
222### `ui.render` 行显示 `threw while drawn`228### `ui.render` 行显示 `threw while drawn`
223 229
224该行会指明[渲染位置](/docs/zh-CN/plugins/mods/reference.md#render-sites),然后显示 `threw while drawn:` 及错误,如 `first-mod: ui.render (ToolUse) threw while drawn: <error>; the engine drew its own`。Claude Code 在绘制您的 [`ui.render`](/docs/zh-CN/plugins/mods/reference#interface) hook 返回的树时,或在根据[您的 hook 传递给 `next` 的 `props`](/docs/zh-CN/plugins/mods/interface#change-what-claude-code-already-draws) 绘制该位置时,遇到了该错误。结尾的 `the engine drew its own` 表示该位置显示 Claude Code 的常规内容。230该行会指明[渲染位置](https://code.claude.com/docs/zh-CN/plugins/mods/reference.md#render-sites),然后显示 `threw while drawn:` 及错误,如 `first-mod: ui.render (ToolUse) threw while drawn: <error>; the engine drew its own`。Claude Code 在绘制您的 [`ui.render`](https://code.claude.com/docs/zh-CN/plugins/mods/reference#interface) hook 返回的树时,或在根据[您的 hook 传递给 `next` 的 `props`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#change-what-claude-code-already-draws) 绘制该位置时,遇到了该错误。结尾的 `the engine drew its own` 表示该位置显示 Claude Code 的常规内容。
225 231
226读取该错误,并修复您的 hook 中导致该错误的值。232读取该错误,并修复您的 hook 中导致该错误的值。
227 233
228在 v2.1.289 之前,会话记录行中出现此错误会导致会话以 [`Claude Code exited after an unrecoverable interface error`](/docs/zh-CN/errors#exited-after-an-unrecoverable-interface-error) 结束。234在 v2.1.289 之前,会话记录行中出现此错误会导致会话以 [`Claude Code exited after an unrecoverable interface error`](https://code.claude.com/docs/zh-CN/errors#exited-after-an-unrecoverable-interface-error) 结束。
229 235
230### `the module failed without a message`236### `the module failed without a message`
231 237
232某个 [`Client`](/docs/zh-CN/plugins/mods/interface#when-a-client-fails) 因一个没有消息的错误而失败,例如 `throw new Error()`。在其位置显示的行类似 `my-mod: Client client/spinner.js: the module failed without a message`。238某个 [`Client`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#when-a-client-fails) 因一个没有消息的错误而失败,例如 `throw new Error()`。在其位置显示的行类似 `my-mod: Client client/spinner.js: the module failed without a message`。
233 239
234在您的 `Client` 代码中找到该 throw,并为该错误提供消息。该行随后会显示该消息。240在您的 `Client` 代码中找到该 throw,并为该错误提供消息。该行随后会显示该消息。
235 241
237 243
238### `$.ui.open` 运行且没有窗格出现244### `$.ui.open` 运行且没有窗格出现
239 245
240调用不是来自用户做的事情,且终端宽度小于[该窗格所需的宽度](/docs/zh-CN/plugins/mods/interface.md#when-a-pane-waits-for-a-wider-terminal)。246调用不是来自用户做的事情,且终端宽度小于[该窗格所需的宽度](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#when-a-pane-waits-for-a-wider-terminal)。
241 247
242从命令或按钮打开窗格,或检查调用的 `isPlaced` 结果。请参阅 [在正确的时间打开窗格](/docs/zh-CN/plugins/mods/interface.md#open-a-pane-at-the-right-time)。248从命令或按钮打开窗格,或检查调用的 `isPlaced` 结果。请参阅 [在正确的时间打开窗格](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#open-a-pane-at-the-right-time)。
243 249
244### toast 不出现250### toast 不出现
245 251
246您的 mod 在交互式终端会话中调用了 [`$.ui.toast`](/docs/zh-CN/plugins/mods/api#show-something-without-starting-a-turn),但您没有看到该 toast。要确认调用已运行,请在[调试日志](#read-the-debug-log)中查找包含您的 mod 名称和 toast 文本的行,如 `$.ui.toast (first-mod): build finished`。然后检查以下原因:252您的 mod 在交互式终端会话中调用了 [`$.ui.toast`](https://code.claude.com/docs/zh-CN/plugins/mods/api#show-something-without-starting-a-turn),但您没有看到该 toast。要确认调用已运行,请在[调试日志](#read-the-debug-log)中查找包含您的 mod 名称和 toast 文本的行,如 `$.ui.toast (first-mod): build finished`。然后检查以下原因:
247 253
248* **缺少该调用对应的行**:查找说明 Claude Code 拒绝该调用原因的行,如 `first-mod: $.ui.toast dropped: timeoutMs is a whole number of ms, 1 to 60000`。254* **缺少该调用对应的行**:查找说明 Claude Code 拒绝该调用原因的行,如 `first-mod: $.ui.toast dropped: timeoutMs is a whole number of ms, 1 to 60000`。
249* **某个窗格正在暂缓 toast**:您的 mod 或其他 mod 在打开当前显示的窗格时传递了 [`holdToasts`](/docs/zh-CN/plugins/mods/interface#hold-toasts-behind-a-dialog)。关闭该窗格即可结束暂缓。如果该窗格是您的且需要保持打开,请从其 `$.ui.open` 调用中移除 `holdToasts`,然后重新打开该窗格。255* **某个窗格正在暂缓 toast**:您的 mod 或其他 mod 在打开当前显示的窗格时传递了 [`holdToasts`](https://code.claude.com/docs/zh-CN/plugins/mods/interface#hold-toasts-behind-a-dialog)。关闭该窗格即可结束暂缓。如果该窗格是您的且需要保持打开,请从其 `$.ui.open` 调用中移除 `holdToasts`,然后重新打开该窗格。
250* **toast 位于输入框下方**:在[经典渲染器](/docs/zh-CN/fullscreen.md#enable-fullscreen-rendering)中,请查看输入框下方的右侧。该处的 toast 是以 mod 名称开头的一行文字,而不是右上角的方框。256* **toast 位于输入框下方**:在[经典渲染器](https://code.claude.com/docs/zh-CN/fullscreen.md#enable-fullscreen-rendering)中,请查看输入框下方的右侧。该处的 toast 是以 mod 名称开头的一行文字,而不是右上角的方框。
251* **您的 mod 发出了更新的 toast**:在经典渲染器中,来自您的 mod 的更新 toast 可能会取代正在显示或等待显示的 toast。调试日志中会有针对较早 toast 的另一行:如果该 toast 当时正在显示,该行以 `gave way, cut short` 结尾;如果它从未出现,则以 `gave way, unseen` 结尾。要同时显示两条消息,请将它们放在一个 toast 中。257* **您的 mod 发出了更新的 toast**:在经典渲染器中,来自您的 mod 的更新 toast 可能会取代正在显示或等待显示的 toast。调试日志中会有针对较早 toast 的另一行:如果该 toast 当时正在显示,该行以 `gave way, cut short` 结尾;如果它从未出现,则以 `gave way, unseen` 结尾。要同时显示两条消息,请将它们放在一个 toast 中。
252* **toast 在绘制前超时**:在全屏渲染中,Claude Code 一次最多绘制三个 toast,因此 toast 可能在绘制之前就已超时。调试日志中会有针对该 toast 的另一行,以 `left the stack, never drawn` 结尾。当您的 mod 同时发出多个 toast 时,请将这些消息放在一个 toast 中。258* **toast 在绘制前超时**:在全屏渲染中,Claude Code 一次最多绘制三个 toast,因此 toast 可能在绘制之前就已超时。调试日志中会有针对该 toast 的另一行,以 `left the stack, never drawn` 结尾。当您的 mod 同时发出多个 toast 时,请将这些消息放在一个 toast 中。
253 259
254在 v2.1.290 之前,如果某个 toast 是在 Claude Code 为您的 mod 显示上一个 toast 后两秒内发出的,Claude Code 会丢弃该 toast,且调试日志中针对被丢弃 toast 的行会显示 `within 2000ms of the last; dropped`。260在 v2.1.290 之前,如果某个 toast 是在 Claude Code 为您的 mod 显示上一个 toast 后两秒内发出的,Claude Code 会丢弃该 toast,且调试日志中针对被丢弃 toast 的行会显示 `within 2000ms of the last; dropped`。
255 261
262### 带显示 `plugin panel hidden`
263
264该带已[折叠](https://code.claude.com/docs/zh-CN/plugins/mods/interface.md#when-the-user-collapses-the-band)。当您按 Ctrl+X 然后 Ctrl+A(或您绑定以替代它们的按键)时,以及在[全屏渲染](https://code.claude.com/docs/zh-CN/fullscreen.md)中单击其第一行的 `[-]` 时,该带会折叠。它会保持折叠状态,直到您将其展开或再次启动 Claude Code;在此期间,任何热键或 `action` 绑定都不会按下其中的按钮。
265
266要展开该带,请按该行所示的按键(默认为 Ctrl+X 然后 Ctrl+A),或在全屏渲染中单击该行。
267
256### 热键不起作用268### 热键不起作用
257 269
258您的窗格没有键盘焦点,或者绘图位于 VS Code 扩展中,而该扩展中的按钮没有热键。请按对应的情况操作:270您的窗格或带没有键盘焦点、您的按钮位于已折叠的带中,或者绘图位于 VS Code 扩展中,而该扩展中的按钮没有热键。请按对应的情况操作:
259 271
260* **没有键盘焦点**:按 Ctrl+X 然后 Tab,或单击窗格。要让窗格在打开时获得焦点,请从命令中使用 `focus: true` 打开它。272* **没有键盘焦点**:按 Ctrl+X 然后 Tab,或在[全屏渲染](https://code.claude.com/docs/zh-CN/fullscreen.md)中单击窗格或带。要让窗格在打开时获得焦点,请从命令中使用 `focus: true` 打开它。
273* **按钮位于已折叠的带中**:该带显示一个以 `▸ plugin panel hidden` 开头的暗色行。按该行所示的按键(默认为 Ctrl+X 然后 Ctrl+A)即可[展开它](#plugin-panel-hidden)。
261* **在 VS Code 扩展中**:单击按钮,或在按钮获得焦点后按 Enter274* **在 VS Code 扩展中**:单击按钮,或在按钮获得焦点后按 Enter
262 275
263### 绘图在终端中有效,在桌面应用或 VS Code 中无效276### 绘图在终端中有效,在桌面应用或 VS Code 中无效
264 277
265要么该应用不绘制该位置或元素,要么该会话属于 VS Code 扩展不为 mod 绘制任何内容的会话。该 mod 的其他 hook 仍会运行。请检查以下原因:278要么该应用不绘制该位置或元素,要么该会话属于 VS Code 扩展不为 mod 绘制任何内容的会话。该 mod 的其他 hook 仍会运行。请检查以下原因:
266 279
267* **该位置或元素在该应用中不会被绘制**:在[渲染位置](/docs/zh-CN/plugins/mods/reference.md#render-sites)表中查找您的位置,并在[元素](/docs/zh-CN/plugins/mods/reference.md#elements)表中查找您的元素。对于该应用不具备的元素,请在 hook 中检查 `e.surface`,并返回该应用可以绘制的树。280* **该位置或元素在该应用中不会被绘制**:在[渲染位置](https://code.claude.com/docs/zh-CN/plugins/mods/reference.md#render-sites)表中查找您的位置,并在[元素](https://code.claude.com/docs/zh-CN/plugins/mods/reference.md#elements)表中查找您的元素。对于该应用不具备的元素,请在 hook 中检查 `e.surface`,并返回该应用可以绘制的树。
268* **VS Code 扩展版本低于 2.1.299**:从[扩展版本](/docs/zh-CN/vs-code.md#install-the-extension) 2.1.299 起,聊天面板才会为 mod 进行绘制。请在 VS Code 的扩展视图中检查版本,并在该处更新扩展。281* **VS Code 扩展版本低于 2.1.299**:从[扩展版本](https://code.claude.com/docs/zh-CN/vs-code.md#install-the-extension) 2.1.299 起,聊天面板才会为 mod 进行绘制。请在 VS Code 的扩展视图中检查版本,并在该处更新扩展。
269* **扩展版本低于 2.1.304,且该会话不获取功能标志**:请更新扩展,或改为在 VS Code 的集成终端中运行 `claude`。在 Amazon Bedrock、Google Cloud 的 Agent Platform 或 Microsoft Foundry 上的会话会跳过此获取步骤。对于跳过此步骤的其他会话,例如 [Claude apps 网关](/docs/zh-CN/claude-apps-gateway)会话,请参阅[需要获取功能标志的功能](/docs/zh-CN/env-vars.md#features-that-need-feature-flag-fetching)。282* **扩展版本低于 2.1.304,且该会话不获取功能标志**:请更新扩展,或改为在 VS Code 的集成终端中运行 `claude`。在 Amazon Bedrock、Google Cloud 的 Agent Platform 或 Microsoft Foundry 上的会话会跳过此获取步骤。对于跳过此步骤的其他会话,例如 [Claude apps 网关](https://code.claude.com/docs/zh-CN/claude-apps-gateway)会话,请参阅[需要获取功能标志的功能](https://code.claude.com/docs/zh-CN/env-vars.md#features-that-need-feature-flag-fetching)。
270 283
271## 编辑或值丢失284## 编辑或值丢失
272 285
282 295
283模块级变量在每次重新加载时重新初始化。296模块级变量在每次重新加载时重新初始化。
284 297
285[将值保留在 `$.state` 或 `$.store` 中](/docs/zh-CN/plugins/mods/interface#keep-state)。298[将值保留在 `$.state` 或 `$.store` 中](https://code.claude.com/docs/zh-CN/plugins/mods/interface#keep-state)。
286 299
287### 值在 `/clear`、`/resume` 或 `/branch` 后重置300### 值在 `/clear`、`/resume` 或 `/branch` 后重置
288 301
289值重置,或保存的值被其默认值替换。这些命令中的每一个都将 `$.state` 重置为其默认值,`session.start` 不再触发。302值重置,或保存的值被其默认值替换。这些命令中的每一个都将 `$.state` 重置为其默认值,`session.start` 不再触发。
290 303
291[在 `classic.SessionStart` hook 中再次加载保存的值](/docs/zh-CN/plugins/mods/interface#load-a-saved-value-again-after-clear)。304[在 `classic.SessionStart` hook 中再次加载保存的值](https://code.claude.com/docs/zh-CN/plugins/mods/interface#load-a-saved-value-again-after-clear)。
292 305
293## 阅读调试日志306## 阅读调试日志
294 307
310hooks module first-mod@inline loaded (worker, environment 2, tier user); events: session.start,tool.call,command.run,ui.render323hooks module first-mod@inline loaded (worker, environment 2, tier user); events: session.start,tool.call,command.run,ui.render
311```324```
312 325
313未验证的绘图计为被拒绝的结果,也会获得一行。要在日志中写入您自己的行,请调用 [`$.ui.log`](/docs/zh-CN/plugins/mods/api#show-something-without-starting-a-turn),带有第二个参数,如 `$.ui.log('message', { to: 'debug' })`。没有第二个参数,`$.ui.log` 会在会话记录中添加一条暗行。326未验证的绘图计为被拒绝的结果,也会获得一行。要在日志中写入您自己的行,请调用 [`$.ui.log`](https://code.claude.com/docs/zh-CN/plugins/mods/api#show-something-without-starting-a-turn),带有第二个参数,如 `$.ui.log('message', { to: 'debug' })`。没有第二个参数,`$.ui.log` 会在会话记录中添加一条暗行。
314 327
315当您编辑使用 `--plugin-dir` 加载的 mod 时,会话记录为每次重新加载显示一行,命名 mod 并列出其 hook。如果保存破坏了模块,该行会显示 `reload failed, the previous version stays loaded:` 及原因,最后一个可用版本会继续运行,直到 Claude Code 下次重新加载插件,例如当您运行 `/reload-plugins` 时。328当您编辑使用 `--plugin-dir` 加载的 mod 时,会话记录为每次重新加载显示一行,命名 mod 并列出其 hook。如果保存破坏了模块,该行会显示 `reload failed, the previous version stays loaded:` 及原因,最后一个可用版本会继续运行,直到 Claude Code 下次重新加载插件,例如当您运行 `/reload-plugins` 时。
316 329
317## 后续步骤330## 后续步骤
318 331
319* [测试 mod](/docs/zh-CN/plugins/mods/test.md):在问题到达会话之前捕获它们332* [测试 mod](https://code.claude.com/docs/zh-CN/plugins/mods/test.md):在问题到达会话之前捕获它们
320* [排查插件问题](/docs/zh-CN/plugins/troubleshooting.md):与安装和加载不特定于 mod 的插件相关的问题333* [排查插件问题](https://code.claude.com/docs/zh-CN/plugins/troubleshooting.md):与安装和加载不特定于 mod 的插件相关的问题