claude-code - 💡(How to fix) Fix Third-party LSP plugins: `.lsp.json` at plugin root works on v2.1.119; marketplace.json `lspServers` alone is silently ignored [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#53399Fetched 2026-04-26 05:16:49
View on GitHub
Comments
1
Participants
2
Timeline
9
Reactions
0
Author
Timeline (top)
labeled ×5cross-referenced ×3commented ×1

Working through the third-party LSP plugin path on Claude Code v2.1.119, I found a gap between the marketplace-side docs and what actually loads, plus two documented config fields that the runtime rejects. Posting the empirical findings as a heads-up for anyone else hitting the same wall.

Error Message

| Manifest with restartOnCrash: true or maxRestarts: N (in any of the three config locations) | Initialization fails. Loader logs [ERROR] LSP server '<id>': restartOnCrash is not yet implemented. Remove this field from the configuration. The entire LSP server is rejected, not just the field. .lsp.json files get No LSP server available. startupTimeout works fine. | The restartOnCrash and maxRestarts fields are listed in the marketplace lspServers schema in the plugins reference, but the runtime rejects them at init with the error above. Either remove them from the docs or implement the runtime side; right now a plugin author copying the documented schema gets a non-loading LSP.

Root Cause

Working through the third-party LSP plugin path on Claude Code v2.1.119, I found a gap between the marketplace-side docs and what actually loads, plus two documented config fields that the runtime rejects. Posting the empirical findings as a heads-up for anyone else hitting the same wall.

Fix Action

Fix / Workaround

  • #15521 was closed as completed in v2.1.76 with the claim that LSP plugin loading was fixed. On 2.1.119 the marketplace-level lspServers path remains inert for third-party marketplaces. The .lsp.json runtime path does work, but that distinction isn't anywhere in the closed issue's comments.
  • #31468 was closed as NOT_PLANNED with a comment that "no configuration-based workaround exists." Empirically there is a working configuration — .lsp.json at the plugin root, or lspServers in plugin.json — and neither is mentioned in any of the comments on that thread. Opening this issue so the next person searching for "third-party LSP plugin not loading" finds the working answer.

Code Example

<marketplace-repo>/
├── .claude-plugin/
│   └── marketplace.json    # plugin entry can include `lspServers`
                             (matches official-plugin shape;
│                             harmless if currently ignored)
└── plugins/
    └── <plugin-name>/
        ├── .claude-plugin/
        │   └── plugin.json   # identity metadata; lspServers can
        │                       also be inlined here as the third
        │                       valid config location
        ├── .lsp.json         # ← THIS file registers the LSP at
runtime (recommended path)
        └── README.md
RAW_BUFFERClick to expand / collapse

Summary

Working through the third-party LSP plugin path on Claude Code v2.1.119, I found a gap between the marketplace-side docs and what actually loads, plus two documented config fields that the runtime rejects. Posting the empirical findings as a heads-up for anyone else hitting the same wall.

Setup

  • Claude Code 2.1.119 on Windows (also tested under WSL)
  • Plugin: zig-lsp distributed via agent-sh/zig-lsp — a third-party marketplace, not claude-plugins-official
  • Language server: zls 0.16.0 on PATH
  • Test workspace: a real Zig 0.17 project with ~900 LOC

What worked, what didn't

SetupResult
lspServers block inline in marketplace.json's plugin entry; no .lsp.json in the plugin sourcePlugin shows enabled, but the LSP never registers. Debug log shows Checking plugin zig-lsp and then nothing — no Loaded N LSP server(s) from plugin line follows.
Same plugin entry copied into the local claude-plugins-official marketplace cache (marketplace.json + an empty plugin source dir)Loads fine: Loaded 1 LSP server(s) from plugin: zig-lsp-test. The behavior is gated on the marketplace name, not on schema.
.lsp.json at the plugin root in the source repo (which gets copied to ~/.claude/plugins/cache/<marketplace>/<plugin>/<version>/.lsp.json on install)Loads. Loaded 1 LSP server(s) from plugin: zig-lsp, Total LSP servers loaded: <N>. ZLS spawns and post-edit diagnostics flow as expected.
lspServers inline in .claude-plugin/plugin.json (alongside name/version/etc., not in marketplace.json)Also loads. Third valid path; not in either docs page.
Manifest with restartOnCrash: true or maxRestarts: N (in any of the three config locations)Initialization fails. Loader logs [ERROR] LSP server '<id>': restartOnCrash is not yet implemented. Remove this field from the configuration. The entire LSP server is rejected, not just the field. .lsp.json files get No LSP server available. startupTimeout works fine.

Two paths the docs describe, three that actually work, two fields that don't

For a third-party LSP plugin on 2.1.119, the loader will pick up its server config from any of:

  1. .lsp.json at the plugin root (documented at /plugins#add-lsp-servers-to-your-plugin)
  2. lspServers inline in .claude-plugin/plugin.json (undocumented; verified via michelsciortino/dart-lsp and a local test)
  3. lspServers inline in .claude-plugin/marketplace.jsononly loads for claude-plugins-official; inert for third-party marketplaces (documented at /plugins-reference#lsp-servers)

The restartOnCrash and maxRestarts fields are listed in the marketplace lspServers schema in the plugins reference, but the runtime rejects them at init with the error above. Either remove them from the docs or implement the runtime side; right now a plugin author copying the documented schema gets a non-loading LSP.

Related / why a fresh issue

  • #15521 was closed as completed in v2.1.76 with the claim that LSP plugin loading was fixed. On 2.1.119 the marketplace-level lspServers path remains inert for third-party marketplaces. The .lsp.json runtime path does work, but that distinction isn't anywhere in the closed issue's comments.
  • #31468 was closed as NOT_PLANNED with a comment that "no configuration-based workaround exists." Empirically there is a working configuration — .lsp.json at the plugin root, or lspServers in plugin.json — and neither is mentioned in any of the comments on that thread. Opening this issue so the next person searching for "third-party LSP plugin not loading" finds the working answer.

What a new user should do today (Claude Code 2.1.119)

For a third-party LSP plugin to register:

<marketplace-repo>/
├── .claude-plugin/
│   └── marketplace.json    # plugin entry can include `lspServers`
│                             (matches official-plugin shape;
│                             harmless if currently ignored)
└── plugins/
    └── <plugin-name>/
        ├── .claude-plugin/
        │   └── plugin.json   # identity metadata; lspServers can
        │                       also be inlined here as the third
        │                       valid config location
        ├── .lsp.json         # ← THIS file registers the LSP at
        │                       runtime (recommended path)
        └── README.md

Schema is server-name → { command, args, extensionToLanguage, initializationOptions, ... } — exactly as documented at /plugins-reference#lsp-servers. But strip restartOnCrash and maxRestarts — they're documented but rejected at runtime today. startupTimeout is fine.

Verify after install with claude --debug:

  • ✓ Working: log contains Loaded N LSP server(s) from plugin: <name> and Total LSP servers loaded: M.
  • ✗ Plugin not picking up config: log contains Checking plugin <name> with no following Loaded line — .lsp.json isn't reaching the cache.
  • ✗ Bad field: log contains Failed to initialize LSP server <id> — usually restartOnCrash or another unimplemented field. Strip it from the manifest and reinstall.

Working reference: agent-sh/zig-lsp v0.1.1 ships .lsp.json + marketplace.json lspServers (no restartOnCrash); verified end-to-end on 2.1.119 (uninstall → reinstall → cold session → Loaded 1 LSP server(s) from plugin: zig-lsp, documentSymbol/hover return real results from a Zig 0.17 codebase).

Asks

  1. Doc note on the lspServers marketplace reference clarifying:
    • For third-party marketplaces, .lsp.json at the plugin root is what registers the server today.
    • lspServers inline in plugin.json is also accepted as an alternative.
    • restartOnCrash and maxRestarts are not yet implemented; including them in any config location fails initialization.
  2. Wire the marketplace lspServers field for third-party marketplaces so plugin authors can ship a single source of truth instead of keeping .lsp.json and the marketplace.json block byte-equivalent.
  3. Implement restartOnCrash / maxRestarts or remove them from the schema until they are.

Happy to test fixes against agent-sh/zig-lsp.

extent analysis

TL;DR

To fix the issue with third-party LSP plugins not loading in Claude Code 2.1.119, use the .lsp.json file at the plugin root or inline lspServers in plugin.json, and remove restartOnCrash and maxRestarts fields from the configuration.

Guidance

  • For third-party LSP plugins, use .lsp.json at the plugin root or inline lspServers in plugin.json to register the LSP server.
  • Remove restartOnCrash and maxRestarts fields from the configuration, as they are not yet implemented and will cause initialization to fail.
  • Verify the fix by checking the log for Loaded N LSP server(s) from plugin: <name> and Total LSP servers loaded: M after installing the plugin with claude --debug.
  • If the plugin is not picking up the configuration, check the log for Checking plugin <name> with no following Loaded line, indicating that .lsp.json is not reaching the cache.

Example

// .lsp.json
{
  "server-name": {
    "command": "...",
    "args": "...",
    "extensionToLanguage": "...",
    "initializationOptions": "...",
    "startupTimeout": 3000
  }
}

Notes

The current implementation only supports startupTimeout and does not support restartOnCrash and maxRestarts. The lspServers field in marketplace.json is only supported for official marketplaces.

Recommendation

Apply the workaround by using .lsp.json at the plugin root or inline lspServers in plugin.json, and remove restartOnCrash and maxRestarts fields from the configuration. This will allow third-party LSP plugins to load correctly in Claude Code

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix Third-party LSP plugins: `.lsp.json` at plugin root works on v2.1.119; marketplace.json `lspServers` alone is silently ignored [1 comments, 2 participants]