Plugin installer: wrong extraction path + infinite recursive nesting for marketplace plugins using plugins/ subdirectory

Resolved 💬 4 comments Opened Mar 17, 2026 by FrankLedo Closed Apr 9, 2026

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

  1. Add a third-party marketplace pointing to a GitHub repo that uses plugins/<name>/ directory structure (same as claude-plugins-official)
  2. Install a plugin from that marketplace: /plugin install <name>@<marketplace>
  3. Run /reload-plugins
  4. Observe: skill not available, load error reported
  5. Check cache: entire repo root is at install path instead of plugin subdirectory contents
  6. With autoUpdate: true, run /reload-plugins multiple 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.

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗