claude-code - 💡(How to fix) Fix Plugin cache lost after CLI auto-update (local/third-party plugins not restored) [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#48985Fetched 2026-04-17 08:54:00
View on GitHub
Comments
1
Participants
2
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
labeled ×4commented ×1cross-referenced ×1

Error Message

settings.json still contains the enabledPlugins and statusLine entries pointing to the now-deleted cache paths, so the user sees no error — features just stop working.

  • No error or warning is shown — plugins silently stop working renameSync(backupPath, oldPath); // error -> restore

Root Cause

From reading the minified cli.js, the plugin autoupdate flow appears to delete the old cache entry before attempting reinstallation. If reinstallation fails (e.g., local directory source not accessible, network issues for GitHub sources), the cache is already gone with no rollback.

Code Example

"extraKnownMarketplaces": {
     "my-plugins": {
       "source": { "source": "directory", "path": "/path/to/local/plugins" }
     }
   }

---

async function updatePlugin(name, scope) {
     const oldPath = getCachePath(name, oldVersion);
     const backupPath = oldPath + '.bak';
     renameSync(oldPath, backupPath);       // backup first
     try {
       const result = await installFromSource(name);
       if (result.success) {
         rmSync(backupPath, { recursive: true }); // success -> delete backup
       } else {
         renameSync(backupPath, oldPath);          // fail -> restore
       }
     } catch (e) {
       renameSync(backupPath, oldPath);            // error -> restore
     }
   }
RAW_BUFFERClick to expand / collapse

Bug Description

After Claude Code auto-updates (e.g., 2.1.90 → 2.1.110), the ~/.claude/plugins/cache/ directory is wiped. Plugins installed from local directory sources and third-party marketplaces are not automatically restored, causing all non-official plugins to silently disappear.

settings.json still contains the enabledPlugins and statusLine entries pointing to the now-deleted cache paths, so the user sees no error — features just stop working.

Steps to Reproduce

  1. Install plugins from a local directory marketplace source:
    "extraKnownMarketplaces": {
      "my-plugins": {
        "source": { "source": "directory", "path": "/path/to/local/plugins" }
      }
    }
  2. Also install a third-party plugin not from an official marketplace (e.g., claude-statusline-hud)
  3. Close Claude Code
  4. Reopen — CLI auto-updates to a new version
  5. All locally-sourced and third-party plugins are gone from ~/.claude/plugins/cache/

Expected Behavior

  • Plugin cache should survive CLI upgrades
  • If cache must be rebuilt, plugins should be automatically reinstalled from their registered sources in installed_plugins.json and extraKnownMarketplaces
  • At minimum, the user should be notified that plugins were removed

Actual Behavior

  • ~/.claude/plugins/cache/ is cleared during upgrade
  • installed_plugins.json entries become orphaned (point to non-existent paths)
  • enabledPlugins in settings.json still references the missing plugins
  • No error or warning is shown — plugins silently stop working
  • statusLine command path breaks silently

Impact

In my case, 18+ plugins were lost, including:

  • All local marketplace plugins (ai-review-reporter, browser-automator, slack-mcp, kusto-query, etc.)
  • claude-statusline-hud (third-party)
  • memex (local directory source)
  • claude-mem (GitHub source)

Root Cause Analysis

From reading the minified cli.js, the plugin autoupdate flow appears to delete the old cache entry before attempting reinstallation. If reinstallation fails (e.g., local directory source not accessible, network issues for GitHub sources), the cache is already gone with no rollback.

Suggested Fix

  1. Don't delete cache during CLI upgrade~/.claude/plugins/cache/ is user data, not a disposable cache. CLI binary updates should not touch it.

  2. Backup-before-delete pattern in the plugin update function:

    async function updatePlugin(name, scope) {
      const oldPath = getCachePath(name, oldVersion);
      const backupPath = oldPath + '.bak';
      renameSync(oldPath, backupPath);       // backup first
      try {
        const result = await installFromSource(name);
        if (result.success) {
          rmSync(backupPath, { recursive: true }); // success -> delete backup
        } else {
          renameSync(backupPath, oldPath);          // fail -> restore
        }
      } catch (e) {
        renameSync(backupPath, oldPath);            // error -> restore
      }
    }
  3. Add a claude plugins restore command that rebuilds cache from installed_plugins.json + registered sources.

  4. Startup integrity check: on launch, compare installed_plugins.json entries against actual cache contents. If mismatched, attempt re-install from source before giving up.

Environment

  • OS: Windows 11 Enterprise
  • Claude Code: upgraded from 2.1.90 → 2.1.110 (auto-update via winget)
  • Install method: winget (Anthropic.ClaudeCode)
  • Plugin sources: local directory, GitHub, third-party marketplace

extent analysis

TL;DR

The most likely fix involves modifying the plugin update function to implement a backup-before-delete pattern, ensuring that the plugin cache is not permanently lost during CLI upgrades.

Guidance

  • Implement a backup-before-delete pattern in the plugin update function to prevent cache loss during upgrades.
  • Consider adding a claude plugins restore command to rebuild the cache from installed_plugins.json and registered sources.
  • Perform a startup integrity check to compare installed_plugins.json entries against actual cache contents and attempt re-installation from source if a mismatch is found.
  • Review the cli.js file to understand the current plugin autoupdate flow and identify potential areas for improvement.

Example

async function updatePlugin(name, scope) {
  const oldPath = getCachePath(name, oldVersion);
  const backupPath = oldPath + '.bak';
  renameSync(oldPath, backupPath);       // backup first
  try {
    const result = await installFromSource(name);
    if (result.success) {
      rmSync(backupPath, { recursive: true }); // success -> delete backup
    } else {
      renameSync(backupPath, oldPath);          // fail -> restore
    }
  } catch (e) {
    renameSync(backupPath, oldPath);            // error -> restore
  }
}

Notes

The provided code snippet assumes the existence of getCachePath, installFromSource, renameSync, and rmSync functions, which may need to be implemented or modified according to the actual codebase.

Recommendation

Apply the suggested backup-before-delete pattern in the plugin update function to prevent cache loss during upgrades, as it provides a safe and reliable way to ensure plugin persistence.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING