[BUG] typescript-lsp plugin fails to spawn on Windows (MSYS2/Git Bash) — ENOENT on `typescript-language-server`

Resolved 💬 3 comments Opened Mar 13, 2026 by jbelik Closed Mar 13, 2026

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 plugin installed via /plugin install typescript-lsp silently fails on Windows with MSYS2/Git Bash. The plugin appears with a green checkmark in /plugin as if everything is fine, but when Claude actually tries to use the LSP tool (e.g. hover, go-to-definition), it fails because the language server process cannot be spawned.

The typescript-language-server binary is installed globally via npm, works perfectly from the shell, but Node.js's child_process.spawn (via libuv uv_spawn) cannot resolve the npm shim script on the PATH.

This likely affects all LSP plugins that reference globally-installed npm binaries on Windows, not just typescript-lsp.

What Should Happen?

The LSP plugin should successfully spawn typescript-language-server and return type information when the LSP tool is invoked (hover, go-to-definition, find-references, etc.).

Additionally, /plugin should surface the spawn failure in its status/errors tab rather than showing a green checkmark for a broken plugin.

Error Messages/Logs

First invocation:


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


Subsequent invocations:


Error performing hover: Failed to sync file open <path>: Cannot send notification to LSP server 'plugin:typescript-lsp:typescript': server is error

Steps to Reproduce

  1. On Windows with MSYS2 or Git Bash as the shell, install the language server globally:

``bash
npm install -g typescript-language-server typescript
``

  1. Verify it works from the shell:

``bash
typescript-language-server --version
# Output: 5.1.3
``

  1. In Claude Code, install the official LSP plugin:

``
/plugin install typescript-lsp
``

  1. Run /plugin — the plugin appears with a green checkmark (misleading)
  2. Ask Claude to use the LSP on any TypeScript file, e.g.:

> "Use the LSP hover on line 25 of src/components/my-component.tsx"

  1. Observe the ENOENT error

Root cause: On Windows, npm install -g creates shell shim scripts (POSIX .sh, .cmd, .ps1) in %APPDATA%\npm. The POSIX shim looks like:

#!/bin/sh
# ...
exec node "$basedir/node_modules/typescript-language-server/lib/cli.mjs" "$@"

While the shell can execute this shim, uv_spawn cannot resolve it. node itself IS resolvable — only the npm shim is not.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.74 (Claude Code)

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Windows Terminal

Additional Information

Two separate issues are reported here:

  1. The spawn failure itselfuv_spawn cannot find npm global shim scripts on Windows. Potential fixes:
  • Use shell: true in spawn options so the shell resolves the shim
  • Resolve .cmd extensions when spawning on Windows (the standard way Windows executes npm shims outside POSIX shells)
  • Allow an env field in LSP plugin config to extend PATH
  • Support absolute paths in the command field
  1. Silent failure in /plugin UI — The plugin shows a green checkmark even though the LSP server cannot start. The spawn error only surfaces when the LSP tool is actually invoked by Claude. The error should be visible in /plugin status or the Errors tab proactively, so users don't think the setup is working when it isn't.

Workaround:

Create a local marketplace plugin that invokes node directly with the cli.mjs entry point, bypassing PATH resolution:

{
  "lspServers": {
    "typescript": {
      "command": "node",
      "args": [
        "C:/Users/<USERNAME>/AppData/Roaming/npm/node_modules/typescript-language-server/lib/cli.mjs",
        "--stdio"
      ],
      "extensionToLanguage": {
        ".ts": "typescript",
        ".tsx": "typescriptreact",
        ".js": "javascript",
        ".jsx": "javascriptreact"
      }
    }
  }
}

This requires creating a full local marketplace structure, registering it with /plugin marketplace add, and installing the patched plugin from it.

View original on GitHub ↗

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