[BUG] LSP plugins installed before the lspServers manifest-format change load as silent empty shells; `plugin update` reports the broken artifact as up-to-date

Status Open
Reported on v2.1.212
Maintainer reply None cached
Activity 2 comments · opened Jul 17, 2026

Summary

LSP plugins installed before the lspServers config moved into the marketplace manifest are silently non-functional: they load as empty shells (no LSP server launched, no error anywhere), and claude plugin update cannot repair them because it compares version strings and pyright-lsp has been 1.0.0 throughout. The only fix is uninstall + install, which nothing tells the user to do.

Related but distinct: #15148 (same symptom on a fresh install, Dec 2025), #61954 (update-says-latest-but-stale, path-based plugins, closed), #41922 (cache ignored marketplace SHA on install, closed — install is indeed fixed; update is not).

Environment

  • Claude Code 2.1.212, macOS 26.5.1 (arm64)
  • pyright-lsp@claude-plugins-official, originally installed 2026-01-29
  • pyright-langserver 1.1.411 on PATH (verified present in the Claude Code process environment)

Reproduction / diagnosis

  1. Plugin installed 2026-01-29; installed_plugins.json shows "version": "1.0.0", "lastUpdated": "2026-01-29" pinned to commit d49ad35, while sibling plugins with "version": "unknown" refreshed themselves continuously.
  2. The Jan-2026 cached artifact at ~/.claude/plugins/cache/claude-plugins-official/pyright-lsp/1.0.0/ contains a generated .claude-plugin/plugin.json with only name/description/version/authorno lspServers key. The current marketplace format instead declares lspServers in the marketplace.json entry (the plugin source dir itself now ships only LICENSE + README).
  3. Result: plugin "loads" successfully every session, /plugin shows it enabled with no errors, but no pyright-langserver child process is ever spawned, no diagnostics are delivered, and no LSP tool is registered. The only visible symptom is the plugin drifting into "Not used recently" (in our case: enabled since January, "not used in 41 days", user assumed it was Claude's choice).
  4. claude plugin update pyright-lsp@claude-plugins-official✔ pyright-lsp is already at the latest version (1.0.0). The version string never changed when the manifest format did, so the updater considers the stale, functionally-broken artifact current.
  5. Fix that works: claude plugin uninstall + claude plugin install, then restart. The fresh install materializes correctly (no generated plugin.json; claude plugin details now reports LSP servers (1) pyright), and after restart diagnostics push + the LSP tool both work.

Why this deserves its own issue

  • Every user who installed any official LSP plugin before the manifest change is in this state today, and nothing in the product surfaces it: no load error, no /plugin Errors entry (the binary-missing case does produce one; this case does not), and update actively reports the broken state as current.
  • The failure mode compounds: "Not used recently" reads as the model isn't choosing to use this plugin, not the plugin is broken, so users deprioritize rather than debug it.

Suggested fixes (any one would do)

  1. plugin update should compare content (marketplace entry hash / commit SHA of the plugin subtree) rather than the version string alone — mirroring what #41922 fixed for install.
  2. Marketplace policy: bump plugin versions on any manifest-affecting change (the format migration shipped behavior-relevant changes under an unchanged 1.0.0).
  3. Startup validation: a plugin whose category/marketplace entry declares lspServers but whose materialized artifact registers zero LSP servers should surface in /plugin Errors instead of loading silently as an empty shell.

View original on GitHub ↗

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