[BUG] Plugin marketplace removal leaves orphaned cache and data directories

Resolved 💬 2 comments Opened Apr 12, 2026 by mayurpise Closed May 24, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

When removing a plugin marketplace via /plugin, the marketplace entry is correctly deleted from ~/.claude/plugins/known_marketplaces.json, but the corresponding cache and data directories are left behind on disk.

This means:

  1. ~/.claude/plugins/cache/<marketplace-name>/ persists with all downloaded plugin builds
  2. ~/.claude/plugins/data/<plugin-name>-<marketplace-name>/ persists with any runtime data
  3. Users accumulate orphaned directories over time with no built-in way to clean them

In my case, removing two third-party marketplaces left ~10.5 MB of orphaned cache:

~/.claude/plugins/cache/draft-plugins/     4.0M  (marketplace removed, cache remained)
~/.claude/plugins/cache/mayurpise-codev/   6.5M  (marketplace removed, cache remained)

The installed_plugins.json no longer references these marketplaces, and known_marketplaces.json only lists the official claude-code-plugins — yet the cache directories persist.

What Should Happen?

When a marketplace is removed via /plugin:

  1. All cached plugin builds under ~/.claude/plugins/cache/<marketplace-name>/ should be deleted
  2. All plugin data under ~/.claude/plugins/data/*-<marketplace-name>/ should be deleted
  3. Any plugin entries in installed_plugins.json referencing that marketplace should be removed

Similarly, when an individual plugin is uninstalled:

  1. Its cache directory (~/.claude/plugins/cache/<marketplace>/<plugin>/) should be deleted
  2. Its data directory (~/.claude/plugins/data/<plugin>-<marketplace>/) should be deleted
  3. Its entry in installed_plugins.json should be removed (this part already works)

Steps to Reproduce

  1. Install a third-party marketplace:

``
/plugin --> Add marketplace --> provide repo URL
``

  1. Install a plugin from that marketplace
  2. Verify cache exists:

``bash
ls ~/.claude/plugins/cache/ # shows <marketplace-name>/ directory
ls ~/.claude/plugins/data/ # may show <plugin>-<marketplace>/ directory
``

  1. Remove the marketplace via /plugin → Remove marketplace
  2. Check again:

``bash
ls ~/.claude/plugins/cache/ # <marketplace-name>/ still exists (BUG)
ls ~/.claude/plugins/data/ # <plugin>-<marketplace>/ still exists (BUG)
cat ~/.claude/plugins/known_marketplaces.json # marketplace entry correctly removed
cat ~/.claude/plugins/installed_plugins.json # plugin entries may still reference it
``

Error Messages/Logs

No error messages — the removal completes silently without cleaning up the filesystem.

Proposed Fix

The marketplace-remove and plugin-uninstall handlers in the CLI should:

// Pseudocode for marketplace removal cleanup
async function removeMarketplace(marketplaceName: string) {
  // 1. Remove from known_marketplaces.json (already implemented)
  await removeFromKnownMarketplaces(marketplaceName);

  // 2. Remove all plugins from this marketplace in installed_plugins.json
  const installedPlugins = await readInstalledPlugins();
  for (const [key, entries] of Object.entries(installedPlugins.plugins)) {
    if (key.endsWith(`@${marketplaceName}`)) {
      delete installedPlugins.plugins[key];
    }
  }
  await writeInstalledPlugins(installedPlugins);

  // 3. Delete cached plugin builds
  const cachePath = path.join(pluginsDir, 'cache', marketplaceName);
  await fs.rm(cachePath, { recursive: true, force: true });

  // 4. Delete plugin runtime data
  const dataDir = path.join(pluginsDir, 'data');
  const dataEntries = await fs.readdir(dataDir);
  for (const entry of dataEntries) {
    if (entry.endsWith(`-${marketplaceName}`)) {
      await fs.rm(path.join(dataDir, entry), { recursive: true, force: true });
    }
  }
}

Similarly for individual plugin uninstall:

async function uninstallPlugin(pluginName: string, marketplaceName: string) {
  // 1. Remove from installed_plugins.json (already implemented)

  // 2. Delete plugin cache
  const cachePath = path.join(pluginsDir, 'cache', marketplaceName, pluginName);
  await fs.rm(cachePath, { recursive: true, force: true });

  // 3. Delete plugin data
  const dataPath = path.join(pluginsDir, 'data', `${pluginName}-${marketplaceName}`);
  await fs.rm(dataPath, { recursive: true, force: true });
}

Environment

  • Claude Code Version: 2.1.104
  • Platform: Anthropic API
  • OS: Ubuntu Linux (6.17.0-1014-nvidia, ARM64)
  • Terminal: VS Code integrated terminal
  • Model: Opus 4.6
  • Is this a regression?: I don't know

Additional Information

Directory structure after marketplace removal (showing the bug)

~/.claude/plugins/
  blocklist.json
  install-counts-cache.json
  installed_plugins.json          # no references to removed marketplaces
  known_marketplaces.json         # only lists "claude-code-plugins"
  cache/
    claude-code-plugins/          # active — has installed plugins
    draft-plugins/                # ORPHANED — marketplace was removed
    mayurpise-codev/              # ORPHANED — marketplace was removed
  data/
    explanatory-output-style-claude-code-plugins/   # active
  marketplaces/
    claude-code-plugins/          # active marketplace repo clone

Manual workaround

Users can manually clean orphaned directories:

# Identify orphaned caches by comparing against known_marketplaces.json
rm -rf ~/.claude/plugins/cache/<removed-marketplace-name>/
rm -rf ~/.claude/plugins/data/*-<removed-marketplace-name>/

View original on GitHub ↗

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