Plugin install/uninstall state gets corrupted across git worktrees (duplicate installed_plugins.json entries, contradictory uninstall/disable errors)
Summary
Installing a plugin (figma@claude-plugins-official) from multiple git worktree checkouts of the same repo caused ~/.claude/plugins/installed_plugins.json to accumulate duplicate/stale entries for that plugin. Once duplicated, claude plugin uninstall / claude plugin disable (both CLI and the /plugin GUI trash button) gave contradictory errors that made cleanup impossible through any supported path.
Environment
- OS: Windows 11 Pro (10.0.22621)
- Setup: two
git worktreecheckouts of the same repository (different directories, different branches) - Plugin:
figma@claude-plugins-official(official marketplace), but the underlying mechanism looks plugin-agnostic
Steps to reproduce
- In worktree A, run
claude plugin install figma@claude-plugins-official(project scope, default). - In worktree B (separate worktree of the same repo), run
claude plugin install figma@claude-plugins-officialagain, more than once within a short window (e.g. re-running the onboarding command a couple of times). - Also install at user scope:
claude plugin install figma@claude-plugins-official --scope user. - Inspect
~/.claude/plugins/installed_plugins.json→ thefigma@claude-plugins-officialkey now holds 4 array entries. Two of them are exact duplicates: samescope: "project", sameprojectPath, sameversion,installedAttimestamps ~1 minute apart. /plugin→ Installed tab showsfigma@claude-plugins-officiallisted 4 separate times.- Attempt cleanup via CLI:
```
claude plugin uninstall figma@claude-plugins-official --scope project
`
This succeeds once (removes one duplicate), but running the *exact same command again in the same directory* fails with:
`
✘ Failed to uninstall plugin "figma@claude-plugins-official": Plugin "figma@claude-plugins-official" is installed in user scope, not project. Use --scope user to uninstall.
installed_plugins.json
even though still contains a scope: "project" entry with a projectPath` matching the current directory.
- Attempt cleanup via the
/pluginGUI instead: deleting the user-scope entry causes the remaining project-scope entries to flip to "disabled". Deleting either remaining entry then fails with:
````
Claude CLI exited with code 1: × Failed to uninstall plugin "figma@claude-plugins-official": Plugin "figma@claude-plugins-official" is enabled at project scope (.claude/settings.json, shared with your team). To disable just for you: claude plugin disable figma@claude-plugins-official --scope local
- Following the suggested fix produces a contradictory error for the exact same plugin/directory:
````
claude plugin disable figma@claude-plugins-official --scope local
✘ Failed to disable plugin "figma@claude-plugins-official": Plugin "figma@claude-plugins-official" is already disabled at local scope
So the tool simultaneously claims the plugin is "enabled at project scope" (blocking uninstall) and "already disabled at local scope" (blocking the suggested remedy). This loop persisted across a full Claude Code restart and an OS reboot.
Suspected root cause
claude plugin installdoes not appear to dedupe/upsert against an existing{scope, projectPath}record ininstalled_plugins.json— each invocation appends a new array element, so repeated installs (re-running onboarding, installing separately per worktree, etc.) accumulate indefinitely.- The "is this plugin enabled at project scope" check used by
uninstall/disableappears to key off presence of theenabledPlugins["<plugin>"]key in the project's.claude/settings.json, rather than its boolean value. A project.claude/settings.jsoncontaining"figma@claude-plugins-official": falsewas reported as "enabled at project scope" and blocked uninstall, despite the value being explicitlyfalse.
Workaround
Backed up and manually edited ~/.claude/plugins/installed_plugins.json to delete the stray/duplicate array entries for the plugin, then ran claude plugin install figma@claude-plugins-official once more to get a single clean scope: "user" entry. No supported CLI or GUI path reached this state without manual file editing.
Impact
No data loss, but the CLI/GUI cleanup attempts (including a wrong-direction fix suggested by the tool's own error message) cost significant troubleshooting time before falling back to manually editing internal state — which shouldn't be necessary for cleaning up a duplicated plugin listing.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗