typescript-lsp plugin: ENOENT on Windows due to bare command name failing to resolve npm .cmd shim
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 executestypescript-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:
- Spawn with
shell: trueonprocess.platform === 'win32'. - Use
cross-spawn— handles this exact case. - Auto-resolve
.cmd/.ps1/.exeviaPATHEXTon Windows before spawning. - Allow user-level override of
lspServers[*].commandinsettings.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.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗