[BUG] LSP plugins fail on Windows: spawn typescript-language-server ENOENT for npm-installed language servers
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
The typescript-lsp and php-lsp plugins fail to start on Windows with ENOENT errors, even when the language servers are correctly installed globally via npm and are accessible from the
command line.
Error Messages
Plugin Errors
└ 2 plugin error(s) detected:
└ plugin:typescript-lsp:typescript: spawn typescript-language-server ENOENT
└ plugin:php-lsp:intelephense: spawn intelephense ENOENT
Environment
- OS: Windows 10 (Build 26200.7623)
- Shell: Git Bash (MSYS2/MinGW64)
- Node.js: (run node --version)
- npm: (run npm --version)
- Claude Code version: (2.1.12 (Claude Code))
What Should Happen?
The LSP Plugins should work
Error Messages/Logs
Steps to Reproduce
- Install language servers globally:
npm install -g typescript-language-server typescript
npm install -g intelephense
- Verify installation works from command line:
where typescript-language-server
# Output: C:\Users\<user>\AppData\Roaming\npm\typescript-language-server
# C:\Users\<user>\AppData\Roaming\npm\typescript-language-server.cmd
typescript-language-server --version
# Works in Git Bash
- Enable the plugins in Claude Code settings
- Restart Claude Code
- Observe ENOENT errors on startup
Root Cause Analysis
npm global installs on Windows create two files:
- typescript-language-server - POSIX shell script (for Git Bash/MSYS2)
- typescript-language-server.cmd - Windows batch file (for CMD/PowerShell)
$ file /c/Users/Sri/AppData/Roaming/npm/typescript-language-server
/c/Users/Sri/AppData/Roaming/npm/typescript-language-server: POSIX shell script, ASCII text executable
$ file /c/Users/Sri/AppData/Roaming/npm/typescript-language-server.cmd
/c/Users/Sri/AppData/Roaming/npm/typescript-language-server.cmd: DOS batch file, ASCII text, with CRLF line terminators
The plugin attempts to spawn typescript-language-server directly using Node.js child_process.spawn(). On Windows, this fails because:
- Windows cannot execute POSIX shell scripts natively
- The .cmd extension is required for Windows batch files when not using a shell
Running directly via Node.js works:
node "C:\Users\Sri\AppData\Roaming\npm\node_modules\typescript-language-server\lib\cli.mjs" --version
# Output: 5.1.3
Suggested Fix
In the LSP plugin spawn code, use one of these approaches:
Option 1: Use shell: true on Windows
const child = spawn(command, args, {
shell: process.platform === 'win32'
});
Option 2: Append .cmd extension on Windows
const cmd = process.platform === 'win32' ? ${command}.cmd : command;
const child = spawn(cmd, args);
Option 3: Use cross-spawn package which handles this automatically
const spawn = require('cross-spawn');
const child = spawn(command, args);
Affected Plugins
- typescript-lsp@claude-plugins-official
- php-lsp@claude-plugins-official
- Potentially any LSP plugin that relies on npm-installed executables
Unaffected Plugins
- gopls-lsp - uses native Go binary
- rust-analyzer-lsp - uses native Rust binary
- csharp-lsp - uses native .NET binary
Workaround
Disable the affected plugins in .claude/settings.local.json:
{
"enabledPlugins": {
"typescript-lsp@claude-plugins-official": false,
"php-lsp@claude-plugins-official": false
}
}
Claude Model
None
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.12 (Claude Code)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Windows Terminal
Additional Information
Additional Context
This is a well-known issue with npm global packages on Windows. References:
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗