Plugin updater leaves stale version directories in cache; loader globs all of them

Resolved 💬 3 comments Opened May 7, 2026 by mistakeknot Closed May 11, 2026

Plugin updater leaves stale version directories in cache; loader globs all of them

Summary

When Claude Code updates an installed plugin from version X to version Y, the new version's source is cloned to ~/.claude/plugins/cache/<marketplace>/<plugin>/<Y>/ and installed_plugins.json is updated to point there. The old <X>/ directory is never deleted. The plugin loader then globs every version present in the cache, registering duplicate skills, MCP tool names, and (for plugins with MCP server instructions) duplicate instruction blocks in the SessionStart system prompt.

Net effect: silent token bloat on every session that grows with each plugin update.

Reproduction

  1. Install a plugin that ships skills (e.g. vercel@claude-plugins-official).
  2. Wait for or force a version bump.
  3. After the update, look at ~/.claude/plugins/cache/claude-plugins-official/vercel/ — both old and new version directories are present.
  4. Start a new Claude Code session and observe the available-skills listing in the SessionStart system reminder. Skills like vercel:ai-sdk appear multiple times, once per cached version.

Observed scope (real environment)

$ ls ~/.claude/plugins/cache/claude-plugins-official/vercel/
0.40.0  0.40.1  0.42.1                     ← installed_plugins.json points only at 0.42.1

$ ls ~/.claude/plugins/cache/interagency-marketplace/interflux/
0.2.67  0.2.68  0.2.69                     ← only 0.2.69 is installed

$ ls ~/.claude/plugins/cache/interagency-marketplace/interlock/
0.2.12  0.2.13  0.2.14                     ← only 0.2.14 is installed

$ ls ~/.claude/plugins/cache/interagency-marketplace/tldr-swinton/
0.7.17  0.7.18  0.7.19                     ← only 0.7.19 is installed

installed_plugins.json correctly shows a single active version per plugin via installPath. The loader is not consulting it.

Token impact (measured)

After cleaning out the stale versions for a user with 60+ enabled plugins, the per-session skill-listing dropped by ~6,300 tokens (139 skills, ~28k chars → previously 266 skills, ~53k chars). Most of that was duplicate descriptions for plugins that had been updated multiple times.

For long-running sessions or users with auto-update enabled, this leak compounds: every plugin update adds another full copy of that plugin's skills/tools/instructions to the session prompt indefinitely.

Two related bugs

  1. Updater leak: Plugin update flow writes new version dir, atomically switches installed_plugins.json, never removes prior version dir.
  1. Loader fan-out: Plugin loader appears to discover plugins by scanning cache directories rather than by reading installed_plugins.json. Even if the updater were fixed, a plugin loader that loads only the version listed in installed_plugins.json would be defense-in-depth — and would also handle the case where users have manually added old versions.

Suggested fixes

  • Updater: After successful version switch, rm -rf the previous installPath. The path is already known from installed_plugins.json before the swap.
  • Loader: Iterate installed_plugins.json entries and load each entry's installPath directly. Don't glob cache/<marketplace>/<plugin>/*.
  • Defense: At session start, log a warning when cache contains version dirs not referenced by installed_plugins.json.

Workaround

Users can run ic publish clean (third-party tool) or manually rm -rf stale version dirs. This shouldn't be necessary.

View original on GitHub ↗

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