Plugin installer: wrong extraction path + infinite recursive nesting for marketplace plugins using plugins/ subdirectory
Summary
The plugin installer has two related bugs when installing plugins from a marketplace that uses the standard plugins/<name>/ subdirectory structure (matching the claude-plugins-official layout).
Environment
- Claude Code version: latest
- OS: macOS Darwin 25.3.0
Bug 1: Wrong extraction path
When the official claude-plugins-official marketplace installs a plugin, it correctly extracts the contents of plugins/<plugin-name>/ into the cache root:
# Correct (claude-plugins-official):
cache/claude-plugins-official/claude-md-management/1.0.0/
├── .claude-plugin/plugin.json ← contents of plugins/claude-md-management/
├── commands/
└── skills/
For a third-party marketplace using the identical plugins/<name>/ structure, the installer instead copies the entire repo root to the cache:
# Broken (third-party marketplace with same structure):
cache/fxl/slack-monitor/0.1.2/
├── CHANGELOG.md ← entire repo root copied
├── LICENSE
├── plugins/ ← plugin content buried here
│ └── slack-monitor/
│ ├── .claude-plugin/plugin.json
│ └── SKILL.md
Because .claude-plugin/plugin.json is not at the cache root, the plugin loader cannot find it and the skill is never registered.
Bug 2: Infinite recursive nesting on auto-update
With autoUpdate: true set in the marketplace config, each update cycle nests the repo root inside itself, producing a deeply recursive directory tree:
cache/fxl/slack-monitor/0.1.2/
└── slack-monitor/
└── 0.1.2/
└── slack-monitor/
└── 0.1.2/
└── ... (repeats dozens of levels deep)
This also produces a "1 error during load" on /reload-plugins and likely causes filesystem performance issues as the tree grows unboundedly.
Steps to Reproduce
- Add a third-party marketplace pointing to a GitHub repo that uses
plugins/<name>/directory structure (same asclaude-plugins-official) - Install a plugin from that marketplace:
/plugin install <name>@<marketplace> - Run
/reload-plugins - Observe: skill not available, load error reported
- Check cache: entire repo root is at install path instead of plugin subdirectory contents
- With
autoUpdate: true, run/reload-pluginsmultiple times and observe recursive nesting growing
Expected Behavior
The installer should extract plugins/<plugin-name>/ contents to the cache root, identical to how it handles claude-plugins-official plugins.
Actual Behavior
- Entire repo root is copied to cache instead of the plugin subdirectory
- Auto-updates recursively nest the repo root inside itself infinitely
- Plugin skill is never registered ("Unknown skill: <name>")
Workaround
Manually delete the corrupted cache (~/.claude/plugins/cache/<marketplace>/) and avoid autoUpdate: true until fixed.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗