[BUG] Plugin marketplace removal leaves orphaned cache and data directories
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:
~/.claude/plugins/cache/<marketplace-name>/persists with all downloaded plugin builds~/.claude/plugins/data/<plugin-name>-<marketplace-name>/persists with any runtime data- 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:
- All cached plugin builds under
~/.claude/plugins/cache/<marketplace-name>/should be deleted - All plugin data under
~/.claude/plugins/data/*-<marketplace-name>/should be deleted - Any plugin entries in
installed_plugins.jsonreferencing that marketplace should be removed
Similarly, when an individual plugin is uninstalled:
- Its cache directory (
~/.claude/plugins/cache/<marketplace>/<plugin>/) should be deleted - Its data directory (
~/.claude/plugins/data/<plugin>-<marketplace>/) should be deleted - Its entry in
installed_plugins.jsonshould be removed (this part already works)
Steps to Reproduce
- Install a third-party marketplace:
````
/plugin --> Add marketplace --> provide repo URL
- Install a plugin from that marketplace
- Verify cache exists:
``bash``
ls ~/.claude/plugins/cache/ # shows <marketplace-name>/ directory
ls ~/.claude/plugins/data/ # may show <plugin>-<marketplace>/ directory
- Remove the marketplace via
/plugin→ Remove marketplace - 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>/This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗