Windows: LSP servers fail with ENOENT because spawn doesn't resolve .cmd files

Resolved 💬 3 comments Opened Apr 15, 2026 by MartinStepar Closed Apr 18, 2026

Description

On Windows, LSP server plugins (e.g. typescript-lsp, php-lsp, kotlin-lsp) fail with:

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

Root Cause

npm global packages on Windows are installed as .cmd wrapper files (e.g. typescript-language-server.cmd). Node.js child_process.spawn without shell: true does not resolve .cmd files — it looks for an exact executable match.

The marketplace.json defines LSP commands without the .cmd extension:

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

Steps to Reproduce

  1. Install Claude Code on Windows
  2. Enable typescript-lsp plugin
  3. Install typescript-language-server globally: npm install -g typescript-language-server typescript
  4. Try any LSP operation on a .ts file
  5. Get ENOENT: no such file or directory, uv_spawn 'typescript-language-server'

Expected Behavior

LSP servers should start successfully on Windows, just as they do on macOS/Linux.

Suggested Fix

When spawning LSP server processes on Windows, either:

  1. Use shell: true option in child_process.spawn
  2. Use the cross-spawn package
  3. Automatically append .cmd to commands on win32 platform

This is a well-known Node.js issue: https://nodejs.org/api/child_process.html#spawning-bat-and-cmd-files-on-windows

Workaround

Manually edit marketplace.json to append .cmd to LSP command values, or use a SessionStart hook to patch it automatically. Note that marketplace.json gets overwritten on plugin updates, so manual edits don't persist.

Environment

  • OS: Windows 11
  • Claude Code: latest stable
  • Affected plugins: all LSP plugins (typescript-lsp, php-lsp, kotlin-lsp, and others)

View original on GitHub ↗

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