typescript-lsp plugin: ENOENT on Windows due to bare command name failing to resolve npm .cmd shim

Resolved 💬 3 comments Opened Apr 20, 2026 by tyedyediggy Closed Apr 20, 2026

Summary

The official typescript-lsp plugin in the claude-plugins-official marketplace is unusable on Windows out of the box. Every LSP call returns:

ENOENT: no such file or directory, uv_spawn 'typescript-language-server'

even though typescript-language-server is installed globally via npm and resolvable on PATH from any shell.

Root cause

marketplace.json declares:

"lspServers": {
  "typescript": {
    "command": "typescript-language-server",
    "args": ["--stdio"],
    ...
  }
}

npm install -g typescript-language-server installs the binary to %APPDATA%\npm\ as three files:

  • typescript-language-server (POSIX shell shim)
  • typescript-language-server.cmd (Windows cmd shim) ← the one Windows actually executes
  • typescript-language-server.ps1 (PowerShell shim)

Node's child_process.spawn(cmd) without shell: true does not resolve .cmd files via PATHEXT. Only cmd.exe does that. So spawning the bare name typescript-language-server on Windows fails with ENOENT, even though the binary is on PATH and runs fine from a shell.

Reproduction

  • Windows 11
  • Node 20+
  • Claude Code latest
  • npm install -g typescript-language-server typescript
  • /plugin install typescript-lsp@claude-plugins-official
  • /reload-plugins
  • Any LSP operation (hover, goToDefinition, findReferences, etc.) → ENOENT

Workaround

Edit ~/.claude/plugins/marketplaces/claude-plugins-official/.claude-plugin/marketplace.json and change the typescript-lsp command field from "typescript-language-server" to "typescript-language-server.cmd". Then /reload-plugins. Works immediately.

This workaround gets overwritten whenever the plugin/marketplace updates and must be re-applied.

Suggested fix

Any of:

  1. Spawn with shell: true on process.platform === 'win32'.
  2. Use cross-spawn — handles this exact case.
  3. Auto-resolve .cmd / .ps1 / .exe via PATHEXT on Windows before spawning.
  4. Allow user-level override of lspServers[*].command in settings.json (also useful for users who install the binary in non-standard locations).

Option 2 (cross-spawn) is the most common fix in the Node ecosystem for this exact bug.

Impact

Every Windows user who installs typescript-lsp from the official marketplace hits this and gets a fully non-functional plugin until they discover the workaround. It's the single most-installed LSP plugin in the marketplace, so the blast radius is broad.

View original on GitHub ↗

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