Repository navigation
fix(lsp): check for bunx before the typescript bunx fallback - #136
Conversation
spawn reports a missing command as an async 'error' event, so the old try/catch never ran and LSPManager waited out the initialize timeout. Resolve bunx with Bun.which first. When it is missing, log the install hint and return undefined. Otherwise spawn the resolved path and drop the dead try/catch. Closes #135
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
There was a problem hiding this comment.
cubic analysis
No issues found across 2 files
Linked issue analysis
| Status | Acceptance criteria | Notes |
|---|---|---|
| ✅ | Return undefined and log the install hint when bunx is missing | TypescriptServer.spawn checks bunx first, then warns and returns undefined when it is unavailable. |
| ✅ | Check bunx using the current process PATH | The Bun.which call receives process.env.PATH, so it uses PATH at call time. |
| ✅ | Spawn the resolved bunx path without the dead try/catch | The fallback spawns the path returned by Bun.which, and the surrounding try/catch is removed. |
| ✅ | Test the missing-bunx fallback and install hint | The new test empties PATH and asserts the fallback returns undefined and logs the hint. |
Architecture diagram
sequenceDiagram
participant LSP as LSPManager
participant TS as TypescriptServer.spawn
participant BUN as Bun.which
participant SPAWN as child_process.spawn
participant LOG as Logger
Note over LSP,LOG: Typescript Server Startup with bunx Fallback
LSP->>TS: schedule() - spawn server
TS->>TS: Check tsserver on PATH
alt tsserver found
TS->>SPAWN: spawn(tsserver, ...)
SPAWN-->>TS: process handle
TS-->>LSP: { process }
else tsserver NOT found - bunx fallback
TS->>BUN: which('bunx', { PATH: env.PATH })
alt bunx NOT found (critical fix)
BUN-->>TS: undefined
TS->>LOG: warn("typescript-language-server not found. Install with: npm install typescript-language-server typescript")
TS-->>LSP: undefined (immediately marks server broken)
else bunx found
BUN-->>TS: absolute path to bunx
TS->>SPAWN: spawn(bunxPath, [...args], { env: BUN_BE_BUN: '1' })
SPAWN-->>TS: process handle
TS-->>LSP: { process }
end
end
Note over LSP: Old behavior: spawn() returned handle even when bunx missing,<br/>causing LSP to wait out initialize timeout instead of failing fast
[Medium impact] The PR appears safe to merge. SummaryThe TypeScript fallback now checks for
Reviews (1) · Last reviewed commit: "fix(lsp): check for bunx before the type..." · Reviewed by Greptile |



Summary
TypescriptServer.spawn's bunx fallback wrappedspawn('bunx', …)in try/catch, butnode:child_process.spawnnever throws for a missing command. It emits an async'error'(ENOENT), as verified under Bun and Node in #134. With no bunx on PATH, spawn returned a handle to a process that never started.LSPManager.schedulethen waited out the initialize timeout instead of marking the server broken, and the "Failed to spawn…" log never appeared.The fix mirrors
biome.tsfrom #134.Bun.which('bunx', { PATH: process.env.PATH ?? '' })runs first, reading PATH at call time rather than Bun's startup copy.log.warn"typescript-language-server not found. Install with: npm install typescript-language-server typescript" and returnsundefined.Scope
Out of scope:
PyrightServer(packages/lsp/src/server/pyright.ts) has the same dead try/catch, as noted in #135. It is not changed here.Verification
TypescriptServer classic fallbackdescribe ofpackages/lsp/test/unit/server.test.ts. It fails against the oldtypescript.tsfrom origin/main and passes with the fix.tsc --noEmitare clean.bun run typecheck(bun check) is unavailable locally; CI uses 1.4.3.Related issue
Closes #135
Checklist
bun run test)bun run lint)BREAKING CHANGE:note is includedSummary by cubic
Fixes the
TypescriptServerbunx fallback so a missingbunxmarks the server broken immediately instead of waiting out the LSP initialize timeout. Closes #135.node:child_process.spawnnever throws for a missing command—it emits an async'error'event—so the old try/catch never ran and returned a handle to a process that never started. The server now resolvesbunxwithBun.which(readingPATHat call time), logs the install hint and returnsundefinedwhenbunxis missing, and spawns the resolved absolute path otherwise, matching theBiomeServerfix from #134. Added a unit test covering the missing-bunxcase.Written for commit 55bd09a. Summary will update on new commits.