Skip to content

ESLint LSP server fails to auto-install on Windows #6365

@fraineralex

Description

@fraineralex

Description

The ESLint LSP server fails to auto-install and start on Windows. Even though ESLint is installed in the project and the configuration is correct, the LSP server doesn't work automatically.

Root Causes

After investigating the source code, I found several Windows-specific issues:

1. npm commands without .cmd extension (Critical)

Location: packages/opencode/src/lsp/server.ts:199-200

await $\`npm install\`.cwd(finalPath).quiet()
await $\`npm run compile\`.cwd(finalPath).quiet()

On Windows, npm is actually npm.cmd (a batch file wrapper). Bun's shell may not correctly resolve these commands, causing the ESLint server installation to fail silently.

Fix: Use npm.cmd on Windows or use Bun's spawn with explicit path resolution.

2. Invalid V8 flag passed to Bun

Location: packages/opencode/src/lsp/server.ts:205

spawn(BunProc.which(), ["--max-old-space-size=8192", serverPath, "--stdio"], ...)

--max-old-space-size is a V8/Node.js flag, but Bun uses JavaScriptCore (not V8). This flag is ignored or could cause unexpected behavior.

Fix: Remove the flag or use a Bun-specific memory limit flag if available.

3. Comparison with other LSP implementations

Other LSP servers in the codebase correctly handle Windows. For example, Oxlint (line 232-234):

const ext = process.platform === "win32" ? ".cmd" : ""
const serverTarget = path.join("node_modules", ".bin", "oxc_language_server" + ext)

The ESLint implementation doesn't follow this pattern for npm commands.

Environment

  • OS: Windows 10/11
  • OpenCode version: Latest
  • Project: Next.js with ESLint 9.x configured

Expected Behavior

When a project has eslint as a dependency and TypeScript/JavaScript files are opened, the ESLint LSP server should automatically download, compile, and start providing diagnostics.

Actual Behavior

The ESLint LSP server fails silently. No lint diagnostics are shown, and the server doesn't start.

Proposed Fix

// In server.ts ESLint.spawn()
const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm"
await $\`${npmCmd} install\`.cwd(finalPath).quiet()
await $\`${npmCmd} run compile\`.cwd(finalPath).quiet()

// Remove or replace the V8 flag
const proc = spawn(BunProc.which(), [serverPath, "--stdio"], {
  cwd: root,
  env: {
    ...process.env,
    BUN_BE_BUN: "1",
  },
})

Labels

  • bug
  • windows

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions