Skip to content

fix(lsp): fall back to downloaded dart sdk when system dart cannot run - #129

Merged
amondnet merged 3 commits into
mainfrom
amondnet/127-dart-system-probe
Oct 22, 2026
Merged

amondnet merged 3 commits into
mainfrom
amondnet/127-dart-system-probe

Conversation

@amondnet

@amondnet amondnet commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

DartServer.spawn (packages/lsp/src/server/dart.ts) used Bun.which('dart') and spawned whatever resolved. A mise shim with no Dart version configured resolves on PATH but exits 1 (mise ERROR No version is set for shim: dart), so the server died instead of using the auto-downloaded SDK. Spawn now probes the system dart first and falls back to the download path when it cannot run.

  • New exported findSystemDart() runs dart --version (async Bun.spawn, same pattern as oxlint's --help probe) and returns the system path only on exit 0.
  • Otherwise it logs a warning with the exit code and the first 200 chars of stderr, and spawn falls through to the existing auto-download path.
  • Scope: findSystemDart is not re-exported publicly (server/index.ts imports only DartServer). This is the src/server/dart.ts:120 item that test(lsp): skip dart integration tests when dart cannot run #128 listed as remaining work.

Verification

  • Two unit tests in packages/lsp/test/unit/server.test.ts use a fake failing and a fake working dart on PATH. They run in a child bun process because Bun.which reads PATH at process startup.
  • Bun 1.4.3: bun run typecheck passes, eslint is clean, and bun test ./test/unit in packages/lsp gives 162 pass / 0 fail.
  • End-to-end on a machine with the broken mise shim: LSPManager on test/fixtures/dart-project skipped the shim, started from the cached SDK in \~/.cache/dora/dart-lsp, reported connected, and workspaceSymbol('Calculator') returned 1 result.
  • The full bun run test was not run locally because the Vue integration tests still fail locally (VueServer and DartServer integration tests fail locally in packages/lsp #127). CI covers it.

Related issue

Refs #127 (it also covers the Vue integration failures, which remain open)

Checklist

  • PR title follows Conventional Commits
  • Tests added or updated (unit tests; the full suite bun run test is left to CI)
  • Lint/format pass (bun run lint)
  • Documentation updated if behavior changed - n/a, no documented behavior changes
  • No breaking change

Summary by cubic

Fixes the Dart LSP server crashing when the system dart resolves on PATH but cannot actually run, such as a mise shim without an SDK version configured. The server now probes the system dart with dart --version and falls back to the auto-downloaded SDK when it cannot run.

  • findSystemDart() looks up dart on the current PATH and returns the resolved path only when dart --version exits 0 in the project root within a 10s timeout.
  • On failure it warns with the exit code, signal, or spawn error, then falls back to the auto-downloaded SDK.
  • Adds in-process unit tests for failing, unspawnable, and working fake dart scripts on PATH, skipped on Windows.

Written for commit a13a4f6. Summary will update on new commits.

Turn on auto-fix

A version-manager shim (e.g. mise) can resolve on PATH but exit non-zero
when no SDK is installed for the project. Probe `dart --version` and use
the system dart only if it exits 0; otherwise log a warning and fall back
to the auto-downloaded SDK.

Refs #127

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

Code Review

This pull request introduces a findSystemDart helper function to verify that the system Dart binary is functional by running its version command before using it, preventing issues with unconfigured version-manager shims. It also adds corresponding unit tests. The review feedback correctly identifies a robustness issue where Bun.spawn could throw a synchronous error due to permission issues, which would crash the LSP server startup instead of falling back to the auto-downloaded SDK. Wrapping the spawning logic in a try-catch block is recommended to handle this safely.

Comment thread packages/lsp/src/server/dart.ts Outdated
@codecov

codecov Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.41379% with 8 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/lsp/src/server/dart.ts 72.41% 8 Missing ⚠️

📢 Thoughts on this report? Let us know!

@amondnet
amondnet marked this pull request as ready for review October 22, 2026 06:44
@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!

@greptile-apps

greptile-apps Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new blocking issue was found.

Summary

The PR checks whether system Dart can run before starting its language server. Failed probes fall back to the downloaded SDK.

  • Dart startup skips system executables that fail a version check.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Dart server requested] --> B[Find Dart on current PATH]
  B --> C{Executable found?}
  C -->|No| F[Use downloaded SDK]
  C -->|Yes| D[Run version check in project root]
  D --> E{Check succeeds?}
  E -->|No or launch error| F
  E -->|Yes| G[Start system Dart language server]
Loading

Reviews (3) · Last reviewed commit: "refactor(lsp): look up system dart on th..." · Reviewed by Greptile

Comment thread packages/lsp/src/server/dart.ts Outdated
Comment thread packages/lsp/src/server/dart.ts Outdated
Comment thread packages/lsp/src/server/dart.ts Outdated
Comment thread packages/lsp/test/unit/server.test.ts
Harden the system dart probe: catch spawn errors, run it in the project root, and bound it
with a 10s timeout. Skip the shell-based tests on Windows.

Refs #127
@amondnet

Copy link
Copy Markdown
Contributor Author

/gemini review

@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.

No issues found across 2 files

Architecture diagram
sequenceDiagram
    participant LSP as LSP Manager
    participant DS as DartServer (dart.ts)
    participant FS as findSystemDart()
    participant PATH as System PATH
    participant BUN as Bun Runtime
    participant DL as Auto-Download SDK

    Note over LSP,DL: Dart LSP Server Startup Flow

    LSP->>DS: spawn(root)
    
    DS->>FS: findSystemDart(root)
    
    FS->>PATH: Bun.which('dart')
    alt System dart found on PATH
        PATH-->>FS: systemDart path
        FS->>BUN: Bun.spawn([dart, '--version'], { cwd: root })
        
        alt Probe succeeds (exit 0)
            BUN-->>FS: exit 0
            FS-->>DS: return systemDart path
        else Probe fails (non-zero exit or spawn error)
            BUN-->>FS: exit != 0 / signal / error
            FS->>FS: Log warning with exit code + stderr
            FS-->>DS: return undefined
        end
    else No system dart on PATH
        PATH-->>FS: undefined
        FS-->>DS: return undefined
    end
    
    alt Valid system Dart available
        DS->>BUN: spawn(systemDart, ['language-server', ...])
        BUN-->>LSP: LSP process started
    else Falling back to auto-downloaded SDK
        DS->>DL: Fetch/download cached Dart SDK
        DL-->>DS: SDK path
        DS->>BUN: spawn(downloadedSDK, ['language-server', ...])
        BUN-->>LSP: LSP process started
    end
Loading

Turn on auto-fix | Re-trigger cubic

greptile-apps[bot]
greptile-apps Bot previously approved these changes Oct 22, 2026
Bun.which defaults to the PATH captured at process startup. Passing process.env.PATH lets
findSystemDart follow the current environment, so its unit tests can run in-process and
count toward coverage instead of probing through a child bun process.

Refs #127
@greptile-apps
greptile-apps Bot dismissed their stale review October 22, 2026 06:58

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

@sonarqubecloud

Copy link
Copy Markdown

@amondnet
amondnet merged commit 669801c into main Oct 22, 2026
10 checks passed
@amondnet
amondnet deleted the amondnet/127-dart-system-probe branch October 22, 2026 07:04
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.

1 participant