Skip to content

fix(lsp): check for bunx before the typescript bunx fallback - #136

Merged
amondnet merged 1 commit into
mainfrom
amondnet/135-ts-bunx-precheck
Oct 23, 2026
Merged

amondnet merged 1 commit into
mainfrom
amondnet/135-ts-bunx-precheck

Conversation

@amondnet

@amondnet amondnet commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

TypescriptServer.spawn's bunx fallback wrapped spawn('bunx', …) in try/catch, but node:child_process.spawn never 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.schedule then waited out the initialize timeout instead of marking the server broken, and the "Failed to spawn…" log never appeared.

The fix mirrors biome.ts from #134.

  • Bun.which('bunx', { PATH: process.env.PATH ?? '' }) runs first, reading PATH at call time rather than Bun's startup copy.
  • When bunx is missing, it logs log.warn "typescript-language-server not found. Install with: npm install typescript-language-server typescript" and returns undefined.
  • Otherwise it spawns the resolved absolute path (which cleared SonarCloud S4036 on fix(lsp): run a pinned @biomejs/biome in the biome bunx fallback #134).
  • The dead try/catch is removed.

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

  • New test "returns undefined with the install hint when bunx is missing" in the TypescriptServer classic fallback describe of packages/lsp/test/unit/server.test.ts. It fails against the old typescript.ts from origin/main and passes with the fix.
  • 173/173 lsp unit tests pass; eslint and tsc --noEmit are clean.
  • Local Bun is 1.3.5, so bun run typecheck (bun check) is unavailable locally; CI uses 1.4.3.

Related issue

Closes #135

Checklist

  • PR title follows Conventional Commits
  • Tests added or updated, and the suite passes (bun run test)
  • Lint/format pass (bun run lint)
  • Documentation updated if behavior changed (no behavior docs affected)
  • No breaking change, or a BREAKING CHANGE: note is included

Summary by cubic

Fixes the TypescriptServer bunx fallback so a missing bunx marks the server broken immediately instead of waiting out the LSP initialize timeout. Closes #135.

node:child_process.spawn never 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 resolves bunx with Bun.which (reading PATH at call time), logs the install hint and returns undefined when bunx is missing, and spawns the resolved absolute path otherwise, matching the BiomeServer fix from #134. Added a unit test covering the missing-bunx case.

Written for commit 55bd09a. Summary will update on new commits.

Turn on auto-fix

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
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Oct 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.00000% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/lsp/src/server/typescript.ts 90.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@amondnet
amondnet marked this pull request as ready for review October 23, 2026 02:37
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cubic analysis

No issues found across 2 files

Linked issue analysis

Linked issue: pleaseai/code-intelligence#135: fix(lsp): typescript bunx fallback never detects a missing bunx — the try/catch around spawn is dead

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
Loading

Turn on auto-fix | Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge.

Summary

The TypeScript fallback now checks for bunx before starting it. When absent, it logs an install hint and returns undefined; otherwise, it starts the resolved path.

  • The TypeScript fallback checks for bunx before launching it.

Reviews (1) · Last reviewed commit: "fix(lsp): check for bunx before the type..." · Reviewed by Greptile

@amondnet
amondnet merged commit c5f57a4 into main Oct 23, 2026
10 checks passed
@amondnet
amondnet deleted the amondnet/135-ts-bunx-precheck branch October 23, 2026 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(lsp): typescript bunx fallback never detects a missing bunx — the try/catch around spawn is dead

1 participant