claude-code - 💡(How to fix) Fix [BUG] /plugin "Will install" iterates hooks path as char/index list [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#54810Fetched 2026-04-30 06:35:19
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
labeled ×4

Error Message

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

Root Cause

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).

Fix Action

Fix / Workaround

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).

Code Example

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

---

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

---

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

---

Will install:
  · Hooks: 0

---

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

---

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

---

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

---

{
     "hooks": {
       "SessionStart": [
         { "hooks": [{ "type": "command", "command": "echo hello" }] }
       ]
     }
   }

---

---
   description: Example skill
   ---
   Hello.

---

{
     "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"
       }
     ]
   }

---

/plugin marketplace add <owner>/repro-marketplace
   /plugin
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • 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:

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

    repro-plugin/hooks/hooks.json:

    {
      "hooks": {
        "SessionStart": [
          { "hooks": [{ "type": "command", "command": "echo hello" }] }
        ]
      }
    }

    repro-plugin/skills/example/SKILL.md:

    ---
    description: Example skill
    ---
    Hello.
  2. Push the plugin to a GitHub repo (<owner>/repro-plugin).

  3. Create a marketplace repo with .claude-plugin/marketplace.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"
        }
      ]
    }
  4. In Claude Code:

    /plugin marketplace add <owner>/repro-marketplace
    /plugin
  5. Navigate to Discoverrepro-plugin → press Enter.

  6. 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.
  7. (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).

extent analysis

TL;DR

The most likely fix is to modify the /plugin interface's preview rendering to correctly resolve the hooks field, either by parsing the string-path or array-of-paths and displaying a meaningful summary or by showing a stable count of hooks.

Guidance

  • Verify that the hooks field in the marketplace entry is correctly formatted as a string-path or array-of-paths.
  • Check the code responsible for rendering the /plugin interface's preview to ensure it is correctly handling the hooks field and displaying the expected information.
  • Consider adding error handling to catch cases where the hooks field is not correctly formatted or resolved.
  • Test the preview rendering with different types of hooks field declarations (e.g., string-path, array-of-paths, inline object) to ensure it is working as expected.

Example

// Example of a correctly formatted marketplace entry with a string-path hooks field
{
  "name": "repro-plugin",
  "description": "Repro for hooks preview bug.",
  "source": { "source": "github", "repo": "<owner>/repro-plugin" },
  "hooks": "./hooks/hooks.json"
}

Notes

The root cause of this issue appears to be related to the same issue reported in #41943, where the marketplace's hooks string is being passed downstream where a resolved hook config object is expected. However, the manifestation of the bug is different in this case, resulting in a UI rendering issue rather than a crash.

Recommendation

Apply a workaround by removing the hooks field from the marketplace entry, allowing hooks to be auto-discovered from ${CLAUDE_PLUGIN_ROOT}/hooks/hooks.json at install time. This will ensure the plugin works correctly, although the marketplace hooks field will not be usable for path-based declarations.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] /plugin "Will install" iterates hooks path as char/index list [1 participants]