[Windows] LSP plugins fail with spawn ENOENT — missing shell:true for .cmd files
Bug Description
The typescript-lsp@claude-plugins-official plugin (and all npm-installed LSP plugins) fail on Windows with:
spawn typescript-language-server ENOENT
This error appears in /doctor output and recurs every session.
Root Cause
The LSP server manager in cli.js spawns language servers using Node.js child_process.spawn() without shell: true in the spawn options.
On Windows, npm global installs create .cmd wrapper scripts (e.g., typescript-language-server.cmd), not native executables. Without shell: true, Node.js spawn() cannot resolve .cmd files — it only looks for .exe, .com, etc.
Buggy Code Location
cli.js (bundled/minified), function Jb4() at approximately position 7325624:
spawn(command, args, {
stdio: ["pipe", "pipe", "pipe"],
env: ...,
cwd: ...,
windowsHide: true
// MISSING: shell: true
})
Suggested Fix
Add shell: true conditionally for Windows:
spawn(command, args, {
stdio: ["pipe", "pipe", "pipe"],
shell: process.platform === "win32", // ADD THIS
env: ...,
cwd: ...,
windowsHide: true
})
Scope of Impact
This affects all LSP plugins that use npm-installed language servers on Windows:
- typescript-lsp (typescript-language-server)
- php-lsp (intelephense)
- Any other plugin where the binary is an npm global .cmd wrapper
LSP plugins using native executables (clangd, rust-analyzer, gopls) are not affected since they ship real .exe files.
Verification
- typescript-language-server IS correctly installed and accessible via shell:
````
C:\Users\dhdav\AppData\Roaming\npm\typescript-language-server.cmd
- Running
typescript-language-server --stdiofrom a terminal works fine - The issue is exclusively that spawn() without shell: true cannot find .cmd files on Windows
Current Workaround
Disable the plugin in ~/.claude/settings.json:
{
"plugins": {
"typescript-lsp@claude-plugins-official": false
}
}
Environment
- OS: Windows 10 Home 10.0.19045
- Node.js: v22.x
- Claude Code: latest (npm global install)
- typescript-language-server: installed globally via npm
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗