[BUG] /plugin "Will install" iterates hooks path as char/index list

Resolved 💬 1 comment Opened Apr 29, 2026 by Shigaeff Closed May 31, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The /plugin interface's "Will install" preview, shown before installing a plugin, renders the marketplace entry's hooks field by iterating it as a generic collection and displaying the iteration keys (character indices for strings, array indices for arrays) instead of resolving the path or showing meaningful hook info.

For a marketplace entry declaring hooks as a documented string-path:

"hooks": "./hooks/hooks.json"

…the preview shows:

Will install:
  · Hooks: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17

Those are the character indices of the path string ./hooks/hooks.json (18 chars, indices 0–17).

Switching to array form:

"hooks": ["./hooks/hooks.json"]

…produces:

Will install:
  · Hooks: 0

…which is the index of the single array element. This is misleading: it suggests the plugin contains zero hooks, when in fact the plugin has a valid hooks/hooks.json at the default path that is correctly auto-discovered at install time. Functionality is unaffected — only the preview UI is wrong.

Related to but distinct from #41943: that issue is in the /reload-plugins code path and crashes only when the plugin has no plugin.json. The bug in this report is in the /plugin preview UI and triggers even when the plugin has a complete plugin.json.

What Should Happen?

The preview should resolve the hooks value correctly. In order of preference:

  1. Resolve string-paths and array-of-paths against the plugin source, read the referenced hooks.json, and display a meaningful summary (e.g., Hooks: SessionStart (1)).
  2. Failing that, show a stable count (e.g., Hooks: 1 hook config declared).
  3. Failing that, fall back to the existing Component summary not available for remote plugin message — which, despite being terse, is more honest than Hooks: 0 (which is actively wrong).

Error Messages/Logs

(No error output — pure UI rendering bug; no exception thrown.)

Steps to Reproduce

  1. Create a minimal plugin with a hooks file. Layout:

``
repro-plugin/
├── .claude-plugin/plugin.json
├── hooks/hooks.json
└── skills/example/SKILL.md
``

repro-plugin/.claude-plugin/plugin.json:
``json
{ "name": "repro-plugin", "description": "Repro for hooks preview bug." }
``

repro-plugin/hooks/hooks.json:
``json
{
"hooks": {
"SessionStart": [
{ "hooks": [{ "type": "command", "command": "echo hello" }] }
]
}
}
``

repro-plugin/skills/example/SKILL.md:
``markdown
---
description: Example skill
---
Hello.
``

  1. Push the plugin to a GitHub repo (<owner>/repro-plugin).
  1. Create a marketplace repo with .claude-plugin/marketplace.json:

``json
{
"name": "repro-marketplace",
"owner": { "name": "Example" },
"plugins": [
{
"name": "repro-plugin",
"description": "Repro for hooks preview bug.",
"source": { "source": "github", "repo": "<owner>/repro-plugin" },
"hooks": "./hooks/hooks.json"
}
]
}
``

  1. In Claude Code:

``
/plugin marketplace add <owner>/repro-marketplace
/plugin
``

  1. Navigate to Discoverrepro-plugin → press Enter.
  1. Observe the Will install section.
  • Expected: Hooks: SessionStart (1) or similar meaningful summary.
  • Actual: Hooks: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17.
  1. (Variant) Change the marketplace entry to "hooks": ["./hooks/hooks.json"], run /plugin marketplace update repro-marketplace, repeat the preview. Now the bug shows Hooks: 0.

Claude Model

Not sure / Multiple models

Is this a regression?

I don't know

Claude Code Version

2.1.123 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

VS Code integrated terminal

Additional Information

Workaround: remove the hooks field from the marketplace entry. Hooks are then auto-discovered from ${CLAUDE_PLUGIN_ROOT}/hooks/hooks.json at install time and the plugin works correctly. This means the marketplace hooks field is currently unusable for path-based declarations — it only works for inline object form (which duplicates content already in the plugin repo).

Related: #41943 — same field/declaration triggers a different downstream bug (a reduce is not a function crash in /reload-plugins) when the plugin has no plugin.json. The root cause analysis there suggests the marketplace's hooks string is being passed downstream where a resolved hook config object is expected. The bug reported here is likely the same root cause manifesting in a different code path (the /plugin preview UI).

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗