[BUG] Project-scope plugin installs are unremovable: uninstall says "enabled at project scope", disable says "already disabled" (still repro on v2.1.199; #62966 stale-closed)

Open 💬 0 comments Opened Jul 3, 2026 by innopoiesis

Summary

A plugin registered at project scope cannot be removed through any documented command sequence:

  • claude plugin uninstall <name>@<market> refuses with

Plugin "<name>@<market>" is enabled at project scope (.claude/settings.json, shared with your team). To disable just for you: claude plugin disable <name>@<market> --scope local

  • The suggested command claude plugin disable <name>@<market> --scope local refuses with already disabled at local scope; --scope project likewise reports already disabled at project scope.

The two guards contradict each other, producing a deadlock. This is the same symptom as #62966, which was closed as stale (NOT_PLANNED) by github-actions on 2026-06-28 with an invitation to open a new issue if still relevant. It is still fully reproducible on v2.1.199 — and on Windows, whereas #62966 was reported on macOS.

Environment

  • Claude Code: 2.1.199 (also reproduced on 2.1.198 earlier the same day)
  • OS: Windows 11 Pro 25H2 (build 26200), PowerShell 7.6.3
  • Reproduced with: superpowers@superpowers-marketplace (project 5.1.0 / user 6.1.1) and skill-codex@skill-codex

Steps to reproduce

  1. Have a plugin registered at project scope in ~/.claude/plugins/installed_plugins.json (entry with "scope": "project", "projectPath": "<proj>"). In our case these were legacy registrations created by earlier installs.
  2. Ensure the plugin appears in no enabledPlugins map: not in <proj>/.claude/settings.json, not in <proj>/.claude/settings.local.json, not in ~/.claude/settings.json (verified by grep), and no per-project entry in ~/.claude.json.
  3. From the project directory run claude plugin uninstall <name>@<market> → rejected: "is enabled at project scope (.claude/settings.json…)".
  4. Run the suggested claude plugin disable <name>@<market> --scope local → rejected: "already disabled at local scope". Same for --scope project.
  5. Repeat step 3 → same rejection. No documented path removes the registration.

Expected vs actual

  • Expected: either uninstall removes a project-scope installation (optionally after a confirmation), or disable clears whatever state the uninstall guard reads. Error messages should not contradict each other.
  • Actual: uninstall's guard appears to read the install registry (treating a project-scope installation as implicitly enabled), while disable reads the settings maps — so each command claims the other's state.

Two additional findings while working around this

  1. uninstall targets user scope first, regardless of cwd. With the same plugin installed at both user (6.1.1) and project (5.1.0) scope, running claude plugin uninstall from the project directory (after removing its settings enablement) removed the user-scope 6.1.1 installation and left both stale project-scope 5.1.0 entries. Surprising and effectively data-losing (the newest install disappears first).
  2. Registry parsing is silently all-or-nothing. While repairing the registry by hand we learned that every value in the plugins map must be an array; if a single entry is written as a plain object, claude plugin list --json returns [] (the entire registry is treated as invalid) with exit 0 and no diagnostic. A per-entry tolerance or an explicit parse error would make recovery much easier.

Workaround (for others hitting this)

Back up and edit ~/.claude/plugins/installed_plugins.json directly: remove the "scope": "project" entries for the affected plugin, keep the value an array, keep the user-scope entry. After that, plugin list and per-project enabledPlugins behave as expected.

Related

  • #62966 — identical uninstall/disable contradiction (macOS, stale-closed NOT_PLANNED 2026-06-28; this issue confirms it is still present on 2.1.199/Windows)
  • #70655 — umbrella report of connected plugin-management issues (scope flag, duplicate entries)

View original on GitHub ↗