Plugin loader uses wrong installPath — takes [0] from installed_plugins array instead of filtering by current project

Resolved 💬 4 comments Opened Apr 10, 2026 by erudenko Closed May 31, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

pluginLoader.ts line 2051 reads:

const installEntry = installedPluginsData.plugins[pluginId]?.[0]

This takes the first entry in the installed_plugins.json array for a given plugin ID without filtering by the current project context. The array is ordered by insertion time (whichever project installed the plugin first is [0]), so the loader reads the installPath from an unrelated project's entry — loading the wrong plugin version, wrong MCP servers, and wrong commands.

The correct filter function already exists in the same codebase — isInstallationRelevantToCurrentProject() in installedPluginsManager.ts (lines 800–808) — but the loader doesn't use it.

Symptoms

When the same plugin is installed across multiple projects at different versions:

  1. Wrong MCP servers loaded — e.g., a deprecated ht-mcp server from terminal plugin v2.0.0 loads in a project that has v4.0.2 (which only uses tmux-mcp)
  2. Wrong commands loaded — old commands like /deep-research appear instead of the current /dev:research
  3. New commands missing — commands added in newer versions don't appear because the old version's commands/ directory is used
  4. The project's own settings.json shows the correct version — claudeup's TUI, /plugins, and installedPluginVersions all report v4.0.2, but the actual loaded content comes from v2.0.0

Root Cause

installed_plugins.json (v2 schema) stores an array of entries per plugin ID, one per project scope:

{
  "version": 2,
  "plugins": {
    "terminal@magus": [
      { "scope": "project", "projectPath": "/Users/jack/mag/website",  "installPath": "~/.claude/plugins/cache/magus/terminal/2.0.0", "version": "2.0.0" },
      { "scope": "project", "projectPath": "/Users/jack/mag/meroku",   "installPath": "~/.claude/plugins/cache/magus/terminal/4.0.2", "version": "4.0.2" },
      ... // 19 more entries from other projects
    ]
  }
}

The loader at pluginLoader.ts:2051 does ?.[0] which returns the website entry (v2.0.0) even when Claude Code is running in the meroku directory (v4.0.2).

Meanwhile, isInstallationRelevantToCurrentProject() already exists and correctly filters:

export function isInstallationRelevantToCurrentProject(
  inst: PluginInstallationEntry,
): boolean {
  return (
    inst.scope === 'user' ||
    inst.scope === 'managed' ||
    inst.projectPath === getOriginalCwd()
  )
}

Suggested Fix

Replace line 2051:

// Before (bug):
const installEntry = installedPluginsData.plugins[pluginId]?.[0]

// After (fix):
const entries = installedPluginsData.plugins[pluginId] ?? []
const installEntry = entries.find(isInstallationRelevantToCurrentProject) ?? entries[0]

The ?? entries[0] fallback preserves current behavior if no entry matches (shouldn't happen in practice).

Steps to Reproduce

  1. Install a marketplace plugin (e.g., terminal@magus) in Project A at version 2.0.0
  2. Later, install the same plugin in Project B at version 4.0.2
  3. Start Claude Code in Project B
  4. Observe: the plugin loads from Project A's cached v2.0.0 directory, not Project B's v4.0.2

Impact

  • Security: old plugin versions may have deprecated/insecure MCP servers that connect and accept tool calls
  • Correctness: wrong commands, wrong skills, wrong MCP tools loaded — breaks the entire plugin experience
  • Confusing UX: every diagnostic (/plugins, settings.json, claudeup) shows the correct version, but the actual runtime behavior uses a different version
  • Scale: the bug worsens as users install plugins across more projects — the first-installed project permanently "wins" the installPath

Related Issues

  • #29074 — Plugin cache not cleared on uninstall/reinstall (related: stale cache versions)
  • #43763 — installed_plugins.json not updated when version changes (related: registry staleness)

Claude Code Version

2.1.98

Platform

Anthropic API (Max)

Operating System

macOS (Darwin 25.4.0, arm64)

Terminal/Shell

Zsh (inside tmux)

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗