Plugin hooks string path format broken in /doctor without deprecation warning
Summary
The hooks field in plugin marketplace.json previously accepted a string path (e.g., "hooks": "./hooks/hooks.json"), which is still shown as valid in the official docs. A recent change broke this format in the /doctor command without a deprecation warning, and the docs still reference the string path format as valid.
Error
Running /doctor produces:
plugin-system: L?.reduce is not a function. (In 'L?.reduce((K,Z)=>K+Z.hooks.length,0)', 'L?.reduce' is undefined)
The minified code expects the hooks value to be an array/object with .reduce(), but receives a string path instead.
Steps to Reproduce
- Create a plugin with
marketplace.jsoncontaining:
``json``
{
"plugins": [{
"name": "my-plugin",
"hooks": "./hooks/hooks.json"
}]
}
- Install the plugin
- Run
/doctor - Observe the
plugin-systemerror
What the Docs Say
The Plugin Manifest Schema in plugins-reference shows the string path format as valid:
{
"hooks": "./config/hooks.json"
}
The Advanced Plugin Entry in plugin-marketplaces shows inline object format:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [{ "type": "command", "command": "..." }]
}
]
}
}
Both formats are documented, but only the inline object format works.
Expected Behavior
Either:
- Support the string path format - resolve the path and load the JSON file before calling
.reduce()in/doctor - Deprecate it properly - show a deprecation warning suggesting migration to inline format or auto-discovery, and update the docs
Workaround
Remove the hooks field from marketplace.json entirely. Claude Code auto-discovers hooks/hooks.json from the plugin directory, so explicit declaration isn't needed. This is what the official hookify plugin does (no hooks field in its marketplace entry).
Environment
- macOS (Darwin 24.6.0)
- Claude Code latest (as of 2026-02-20)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗