[BUG] Manage Plugins lists the same plugin once per install record, so two checkouts of one repo produce identical indistinguishable rows

Status Open
Reported on v2.1.220
Maintainer reply None cached
Activity 0 comments · opened Aug 11, 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?

The Manage Plugins panel in the VS Code extension renders one row per install record rather than one row per plugin. Because a local-scope install is keyed by projectPath, the same plugin enabled in two checkouts of the same repo shows up as two visually identical rows — same name, same marketplace, same version, no project path, no scope label, nothing to distinguish them.

There's no way to tell which row is which, or which one the enable toggle and trash icon will act on. The row count grows with every additional checkout or worktree the plugin is enabled in.

What Should Happen?

One row per plugin. Either:

  • filter the list to records matching the current project path (plus user-scope records), or
  • dedupe by name@marketplace and show scope / project count as secondary text — e.g. local · 2 projects.

If rows must stay separate, they need to be distinguishable — at minimum, show the projectPath on local- and project-scope rows.

Steps to Reproduce

  1. Two directories containing the same repo, e.g. ~/Projects/foo and ~/Projects/foo-clone.
  2. In each, enable the same marketplace plugin at local scope — .claude/settings.local.json:

``json
{ "enabledPlugins": { "my-plugin@my-marketplace": true } }
``

  1. Start a session in each directory so both auto-install.
  2. Open Manage Plugins → Plugins tab, in either project.

Actual: two identical my-plugin@my-marketplace rows under INSTALLED.

~/.claude/plugins/installed_plugins.json holds two entries differing only by projectPath, both pointing at the same installPath:

"my-plugin@my-marketplace": [
  {
    "scope": "local",
    "projectPath": "/Users/me/Projects/foo",
    "installPath": ".../plugins/cache/my-marketplace/my-plugin/1.0.2",
    "version": "1.0.2"
  },
  {
    "scope": "local",
    "projectPath": "/Users/me/Projects/foo-clone",
    "installPath": ".../plugins/cache/my-marketplace/my-plugin/1.0.2",
    "version": "1.0.2"
  }
]

No manual JSON editing is needed to reach this state — opening a session in the second checkout is sufficient. I watched the second record appear on its own after starting a session in the clone.

Deleting the entries from installed_plugins.json doesn't help: the next session in each project re-creates them, because the enable lives in per-project settings.

Claude Code Version

2.1.220

Is this a regression?

I don't know

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

VS Code integrated terminal

Claude Model

Not sure

Additional Context

  • Claude Code 2.1.220 (native install) · extension anthropic.claude-code 2.1.220-darwin-arm64 · VS Code 1.130.0 · macOS 26.5.2 (arm64) · plugin from a private GitHub marketplace.
  • Functionally harmless as far as I can tell — both records share one cache dir, so the plugin loads once per session. This is a display and affordance issue, not a loading failure.
  • Moving the enable to user scope collapses it to one row, but that defeats the purpose: the plugin is intentionally scoped to one repo.

Prior art:

  • #51262 is the same bug, reported at 13 projects with the same dedupe-or-label ask. It was closed as not_planned by the staleness bot and then locked, so commenting there isn't possible — hence this issue.
  • #70655 "Bug 4" is also this bug, embedded as one of four issues in a Windows-platform report about plugin scope management.

Neighboring on-disk bugs that may share a code path:

  • #85278 — duplicate and stale records across git worktree checkouts, plus contradictory uninstall/disable errors that make cleanup impossible.
  • #83767 — project-scope records overwritten across projects instead of upserted by projectPath. Worth flagging that on 2.1.220/macOS my two records coexist rather than overwriting each other, which is the opposite outcome — so either that was fixed, or it's platform- or version-dependent. Mentioning in case the same reconciliation step is responsible for both.

View original on GitHub ↗