fix(lsp): crash when client does not send workspaceFolders in InitializeParams#9557
Conversation
🦋 Changeset detectedLatest commit: 2a6706e The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughLSP server watched-files setup now uses the client-provided root URI when workspace folders are absent via a new Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip You can validate your CodeRabbit configuration file in your editor.If your editor has YAML language server, you can enable auto-completion and validation by adding |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.changeset/fix-lsp-missing-workspace-folders.md:
- Line 5: Update the changeset file
.changeset/fix-lsp-missing-workspace-folders.md so the first line begins with
the required bug-fix prefix "Fixed [`#NUMBER`](PR link): " followed by the summary
(e.g. "Fixed [`#9557`](https://github.com/biomejs/biome/pull/9557): Fix LSP server
crash when client omits workspaceFolders; use rootUri for file watcher
registration"), replacing NUMBER and link with the actual PR/issue details;
ensure the rest of the message stays intact and follows the project's changeset
formatting convention.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9c9209f3-7e24-47fa-9c2b-7aa514420cd2
📒 Files selected for processing (1)
.changeset/fix-lsp-missing-workspace-folders.md
528aaa1 to
56528dd
Compare
|
the changeset references an issue, but the pr description does not mention it |
dyc3
left a comment
There was a problem hiding this comment.
I'm not an expert on the LSP server, but tentatively, i'd say it looks good.
Please link to the issue in your pr description so the issue will auto close, eg fixes #9557
| "@biomejs/biome": patch | ||
| --- | ||
|
|
||
| Fixed [#9557](https://github.com/biomejs/biome/pull/9557): LSP server crash when the client does not send `workspaceFolders` in `InitializeParams`. The file watcher registration now uses the original `rootUri` directly instead of round-tripping through a filesystem path. |
There was a problem hiding this comment.
Changesets must be user-facing, not technical. Please reword it so that we explain which use case we fixed
There was a problem hiding this comment.
Done. Since I didn't find any issues, I referenced the PR. Let me know if this approach is correct. I followed the suggestion from coderabbitai.
Before this commit, when the client did not send workspaceFolders
in InitializeParams, setup_capabilities() converted the rootUri
to a filesystem path via base_path(), then tried to parse that
path back as a URI with Uri::from_str().unwrap(). Since a bare
filesystem path is not a valid URI, this panicked with
ParseError { index: 0, kind: UnexpectedChar }.
After this commit, a new base_uri() method returns the original
rootUri directly, avoiding the lossy path-to-URI round-trip.
This matches what the workspaceFolders branch already does with
folder.uri.
fefe141 to
2a6706e
Compare
Summary
Fix LSP server crash when the client sends only
rootUriwithoutworkspaceFoldersinInitializeParams.The bug
When Biome's LSP server starts, it registers file watchers (for
biome.json,.editorconfig, etc.) insetup_capabilities(). There are two code paths:Path 1: client sends
workspaceFolders(works):VSCode always sends
workspaceFoldersin the init request, so this path always runs for VSCode users and the bug was never caught.Path 2: client sends only
rootUri(crashes):session.base_path()takes therootUri(file:///Users/foo/project) and converts it to a filesystem path (/Users/foo/project). Then the code tries to parse/Users/foo/projectback as a URI. But a bare filesystem path is not a valid URI; URIs require a scheme likefile://. SoUri::from_strfails at the first character, and.unwrap()panics:Context
The LSP specification defines
workspaceFoldersinInitializeParamsas optional.rootUriis the primary way to identify the workspace,workspaceFolderswas added later for multi-root support.Emacs
lsp-modeonly includesworkspaceFoldersinInitializeParamswhen the LSP client is registered as multi-root. Clients likelsp-biomedon't opt into multi-root, so the init request containsrootUribut noworkspaceFolders. This is spec-compliant. VSCode always sendsworkspaceFolders, so the fallback path was never exercised there.The first path (with
workspaceFolders) uses URI objects directly, which works. The second path (withoutworkspaceFolders) round-tripsURI -> filesystem path -> URI, and the conversion back is missing thefile://scheme.The fix
Instead of the broken round-trip, added
session.base_uri()which returns the originalrootUrias-is, no conversion needed. This mirrors what the first path already does withfolder.uri.Changes
crates/biome_lsp/src/session.rs: Addbase_uri()method that returns the originalrootUrifrom the client.crates/biome_lsp/src/server.rs: Usebase_uri()for theRelativePatternbase URI in the fallback path. Remove unuseduse std::str::FromStrimport.crates/biome_lsp/src/server.tests.rs: Add regression testinitialize_without_workspace_folders_does_not_panicthat initializes the server withdidChangeWatchedFiles.dynamicRegistration: trueandworkspace_folders: None, then callsinitializedto triggersetup_capabilities.Test Plan
ParseError { index: 0, kind: UnexpectedChar }), fails without the fix, passes with itlsp-mode+lsp-biome(which does not sendworkspaceFoldersinInitializeParams): editing, saving, and formatting.tsfiles all work without errors after the fix