Skip to content

fix(lsp): reparse open documents after settings load - #11276

Draft
dyc3 wants to merge 1 commit into
mainfrom
dyc3/embedded-language-config-reparse
Draft

fix(lsp): reparse open documents after settings load#11276
dyc3 wants to merge 1 commit into
mainfrom
dyc3/embedded-language-config-reparse

Conversation

@dyc3

@dyc3 dyc3 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

implemented by gpt 5.6 sol

fixes #11275

This is the class of bug that salsa will hopefully help us avoid (when/if we integrate it more).

Here's my clanker's abbreviated explanation of the bug:

The bug required this sequence:

  1. The editor opened an Astro, Vue, or Svelte file.
  2. Biome had not yet discovered or applied the nested biome.json enabling full HTML support.
  3. Biome therefore parsed the document using the legacy JavaScript source.
  4. Project scanning later discovered the nested configuration and enabled full HTML support.
  5. Biome updated its settings, but did not reparse documents that were already open.
  6. A formatting request then combined the new settings with the old parsed document.

The central problem was that configuration and parsed state could disagree:

Current settings: full HTML support enabled
Stored source: legacy JavaScript/Astro
Stored tree: script/frontmatter only

Before the fix, update_settings installed the new settings and invalidated the analyzer cache, but left the parsed document untouched. The updated method now reparses affected documents at crates/biome_service/src/workspace/server.rs:2584.

Test Plan

added tests

Docs

@changeset-bot

changeset-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3ead319

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

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

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

✅ Organic activity

No automation signals detected in the analyzed events.

View full analysis →

This is an automated analysis by AgentScan

@github-actions github-actions Bot added the A-Project Area: project label Aug 7, 2026
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Workspace settings updates now reparse eligible open documents that contain embedded languages. Embedded capability lookup uses the supplied DocumentFileSource. Tests cover formatting and markup preservation for Astro, Vue, Svelte, HTML and SVG files. Tests also verify that enabling embedded snippet support updates an already-open TSX document and detects six snippets. A patch changeset documents the fixes.

Possibly related PRs

Suggested labels: A-LSP, A-Formatter, A-Parser, L-HTML, L-JavaScript

Suggested reviewers: ematipico, mokto

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The implementation reparses affected documents after settings changes and adds tests for preserved Astro, Vue, and Svelte formatting [#11275].
Out of Scope Changes check ✅ Passed The changeset, service changes, and tests all support configuration-change reparsing and embedded-language formatting objectives.
Title check ✅ Passed The title clearly describes the main change: reparsing open documents after settings load.
Description check ✅ Passed The description explains the configuration and reparsing bug, links the issue, and identifies the added tests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dyc3/embedded-language-config-reparse

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/biome_service/src/workspace/server.rs`:
- Around line 643-655: The update loop around open_file_internal must not commit
a stale snapshot after the document collection is released. Revalidate that the
document still has the captured version and content before committing, or
serialize the reparse with change_file so a newer client edit cannot be
overwritten; preserve the newer version and text when they differ. Add a
regression test that interleaves a settings update with change_file and verifies
the newer edit remains effective.

In `@crates/biome_service/src/workspace/server.tests.rs`:
- Around line 218-225: Update format_astro_after_enabling_full_html_support to
assert the complete formatted Astro document, including both --- frontmatter
delimiters, the formatted JavaScript declaration, and the <p>{foo}</p> body; do
not rely only on the body fragment so removal of frontmatter fences fails the
regression test.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a3973a63-7d14-4bcb-a84f-d8fdf9006083

📥 Commits

Reviewing files that changed from the base of the PR and between f3a9868 and 25ee2fe.

📒 Files selected for processing (3)
  • .changeset/fix-embedded-lsp-formatting.md
  • crates/biome_service/src/workspace/server.rs
  • crates/biome_service/src/workspace/server.tests.rs

Comment on lines +643 to +655
for (path, content, version, document_file_source) in updates {
self.open_file_internal(
OpenFileReason::ClientRequest,
OpenFileParams {
project_key,
path: path.into(),
content: FileContent::FromClient { content, version },
document_file_source: Some(document_file_source),
persist_node_cache: true,
inline_config: None,
editor_features: None,
},
)?;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Prevent a stale reparse from overwriting a newer client edit.

These lines reopen a document snapshot after line 641 releases the document collection. If change_file accepts version N + 1 in that interval, this call parses version N and open_file_internal can store the old content and reduce the recorded version through its min merge logic. Formatting and diagnostics can then use stale text.

Make the reparse commit conditional on the same document version and content, or serialise it with client changes. Add a regression test that interleaves a settings update with change_file.

As per coding guidelines, bug fixes require a reproducing regression test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/biome_service/src/workspace/server.rs` around lines 643 - 655, The
update loop around open_file_internal must not commit a stale snapshot after the
document collection is released. Revalidate that the document still has the
captured version and content before committing, or serialize the reparse with
change_file so a newer client edit cannot be overwritten; preserve the newer
version and text when they differ. Add a regression test that interleaves a
settings update with change_file and verifies the newer edit remains effective.

Source: Coding guidelines

Comment on lines +218 to +225
#[test]
fn format_astro_after_enabling_full_html_support() {
assert_format_after_enabling_full_html_support(
"index.astro",
"astro",
"---\nconst foo= 1;\n---\n<p>{foo}</p>\n",
"<p>{foo}</p>",
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Assert that Astro frontmatter fences remain present.

The helper only checks formatted JavaScript and <p>{foo}</p>. Output with both --- delimiters removed still passes. Assert the frontmatter delimiters and body structure, or assert the complete formatted document.

As per coding guidelines, bug fixes require a reproducing regression test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/biome_service/src/workspace/server.tests.rs` around lines 218 - 225,
Update format_astro_after_enabling_full_html_support to assert the complete
formatted Astro document, including both --- frontmatter delimiters, the
formatted JavaScript declaration, and the <p>{foo}</p> body; do not rely only on
the body fragment so removal of frontmatter fences fails the regression test.

Source: Coding guidelines

@codspeed-hq

codspeed-hq Bot commented Aug 7, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 4 untouched benchmarks
⏩ 282 skipped benchmarks1


Comparing dyc3/embedded-language-config-reparse (3ead319) with main (f3a9868)

Open in CodSpeed

Footnotes

  1. 282 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@ematipico ematipico left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is an LSP issue, not a workspace issue. With this solution, the CLI is also paying the price for the synchronization solution by reparsing documents that are stored in the workspace. Plus you introduced a side effect now. update_settings now doesn't update settings anymore, it does more.

No, I think the solution belongs to LSP, and the solution doesn't belong to snippets exclusively (maybe it's evident with snippets?). Simply, there's a situation where our internal data are stale because a document is read before we could read the settings.

@ematipico

Copy link
Copy Markdown
Member

Thinking more, the proposed solution shouldn't even use open_file_internal, but change_file. The document is already in the workspace.

As for the bug, the reproduction is even easier: open Vue file, then open the configuration and enable full support, switch back to the Vue file. Diagnostics and actions should be out of sync.

That's because our parsing strategy changes based on settings, so not even salsa can save us unless we make settings/options a computed product of salsa.

For the solution, I would take a different approach: when we finish loading the settings (Biome and extension), before pulling the diagnostics, launch a spawn_blocking task that loop over the open documents (the ones in the Session, not the workspace), and call workspace.change_file serially

@dyc3
dyc3 marked this pull request as draft August 8, 2026 11:05
@dyc3 dyc3 changed the title fix(service): reparse documents after config changes fix(lsp): reparse open documents after settings load Aug 8, 2026
@dyc3
dyc3 force-pushed the dyc3/embedded-language-config-reparse branch from 25ee2fe to 3ead319 Compare August 8, 2026 21:34
@github-actions github-actions Bot added the A-LSP Area: language server protocol label Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LSP Area: language server protocol A-Project Area: project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 LSP formatting deletes Astro frontmatter/HTML in multi-project workspaces (html.experimentalFullSupportEnabled)

2 participants