Skip to content

fix(service): don't duplicate snippet's trivia when updating snippets#9051

Merged
dyc3 merged 1 commit intonextfrom
dyc3/fix-duplicated-trivia-embedded-snippets
Feb 13, 2026
Merged

fix(service): don't duplicate snippet's trivia when updating snippets#9051
dyc3 merged 1 commit intonextfrom
dyc3/fix-duplicated-trivia-embedded-snippets

Conversation

@dyc3
Copy link
Contributor

@dyc3 dyc3 commented Feb 13, 2026

Summary

update_snippets was duplicating snippets trivia. The root cause was read_leading_trivia grabs the trivia from the original snippet. It then concatenated the leading trivia on the snippet's new code, which also contained leading whitespace. The result was duplicated whitespace. The same thing was happening to the trailing trivia as well.

No changeset since this is a regression from the current main, and it hasn't been released yet.

Fixes #9050

Test Plan

snapshots

Docs

@changeset-bot
Copy link

changeset-bot bot commented Feb 13, 2026

⚠️ No Changeset found

Latest commit: 9661ff4

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions bot added A-CLI Area: CLI A-Project Area: project labels Feb 13, 2026
@dyc3 dyc3 force-pushed the dyc3/fix-duplicated-trivia-embedded-snippets branch from fe6f5da to 9661ff4 Compare February 13, 2026 17:26
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 13, 2026

Walkthrough

This pull request fixes an issue where extra newlines were being added to embedded Vue <script> tags during linting fixes. The fix trims whitespace in the HTML file handler's update_snippets method to prevent duplication of surrounding trivia. A new test case verifies that embedded snippet handling no longer introduces unwanted newlines.

Suggested labels

L-HTML

Suggested reviewers

  • ematipico
  • arendjr
🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (234 files):

⚔️ .claude/agents/biome-lint-engineer.md (content)
⚔️ .claude/agents/cst-parser-engineer.md (content)
⚔️ .claude/agents/ir-formatter-engineer.md (content)
⚔️ .devcontainer/devcontainer.json (content)
⚔️ .editorconfig (content)
⚔️ .github/renovate.json5 (content)
⚔️ .github/workflows/autofix.yml (content)
⚔️ .github/workflows/benchmark_configuration.yml (content)
⚔️ .github/workflows/benchmark_css.yml (content)
⚔️ .github/workflows/benchmark_graphql.yml (content)
⚔️ .github/workflows/benchmark_js.yml (content)
⚔️ .github/workflows/benchmark_json.yml (content)
⚔️ .github/workflows/benchmark_manifests.yml (content)
⚔️ .github/workflows/benchmark_module_graph.yml (content)
⚔️ .github/workflows/benchmark_tailwind.yml (content)
⚔️ .github/workflows/beta.yml (content)
⚔️ .github/workflows/beta_js_api.yml (content)
⚔️ .github/workflows/preview.yml (content)
⚔️ .github/workflows/pull_request_js.yml (content)
⚔️ .github/workflows/pull_request_markdown.yml (content)
⚔️ .github/workflows/pull_request_node.yml (content)
⚔️ .github/workflows/release.yml (content)
⚔️ .github/workflows/release_cli.yml (content)
⚔️ .github/workflows/release_js_api.yml (content)
⚔️ .github/workflows/repository_dispatch.yml (content)
⚔️ AGENTS.md (content)
⚔️ AGENTS.md~next (content)
⚔️ Cargo.lock (content)
⚔️ Cargo.toml (content)
⚔️ Dockerfile.benchmark (content)
⚔️ benchmark/package.json (content)
⚔️ crates/biome_analyze/src/analyzer_plugin.rs (content)
⚔️ crates/biome_analyze/src/lib.rs (content)
⚔️ crates/biome_analyze/src/rule.rs (content)
⚔️ crates/biome_analyze/src/signals.rs (content)
⚔️ crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs (content)
⚔️ crates/biome_cli/src/execute/migrate/unsupported_rules.rs (content)
⚔️ crates/biome_cli/tests/cases/handle_vue_files.rs (content)
⚔️ crates/biome_cli/tests/commands/check.rs (content)
⚔️ crates/biome_cli/tests/snapshots/main_commands_check/check_help.snap (content)
⚔️ crates/biome_cli/tests/snapshots/main_commands_ci/ci_help.snap (content)
⚔️ crates/biome_cli/tests/snapshots/main_commands_format/format_help.snap (content)
⚔️ crates/biome_configuration/Cargo.toml (content)
⚔️ crates/biome_configuration/src/analyzer/linter/rules.rs (content)
⚔️ crates/biome_configuration/src/formatter.rs (content)
⚔️ crates/biome_css_analyze/Cargo.toml (content)
⚔️ crates/biome_css_analyze/src/assist.rs (content)
⚔️ crates/biome_css_analyze/src/assist/source.rs (content)
⚔️ crates/biome_css_analyze/src/keywords.rs (content)
⚔️ crates/biome_css_analyze/src/lint.rs (content)
⚔️ crates/biome_css_analyze/src/lint/a11y.rs (content)
⚔️ crates/biome_css_analyze/src/lint/a11y/use_generic_font_names.rs (content)
⚔️ crates/biome_css_analyze/src/lint/complexity.rs (content)
⚔️ crates/biome_css_analyze/src/lint/correctness.rs (content)
⚔️ crates/biome_css_analyze/src/lint/nursery.rs (content)
⚔️ crates/biome_css_analyze/src/lint/nursery/no_deprecated_media_type.rs (content)
⚔️ crates/biome_css_analyze/src/lint/nursery/no_hex_colors.rs (content)
⚔️ crates/biome_css_analyze/src/lint/style.rs (content)
⚔️ crates/biome_css_analyze/src/lint/suspicious.rs (content)
⚔️ crates/biome_css_analyze/src/registry.rs (content)
⚔️ crates/biome_css_analyze/tests/specs/a11y/useGenericFontNames/invalid.css (content)
⚔️ crates/biome_css_analyze/tests/specs/a11y/useGenericFontNames/invalid.css.snap (content)
⚔️ crates/biome_css_analyze/tests/specs/a11y/useGenericFontNames/valid.css (content)
⚔️ crates/biome_css_analyze/tests/specs/a11y/useGenericFontNames/valid.css.snap (content)
⚔️ crates/biome_css_analyze/tests/specs/correctness/noUnknownFunction/valid.css (content)
⚔️ crates/biome_css_analyze/tests/specs/correctness/noUnknownFunction/valid.css.snap (content)
⚔️ crates/biome_css_formatter/Cargo.toml (content)
⚔️ crates/biome_css_parser/Cargo.toml (content)
⚔️ crates/biome_diagnostics_categories/src/categories.rs (content)
⚔️ crates/biome_formatter/CONTRIBUTING.md (content)
⚔️ crates/biome_graphql_analyze/src/lint.rs (content)
⚔️ crates/biome_graphql_analyze/src/lint/correctness.rs (content)
⚔️ crates/biome_graphql_analyze/src/lint/nursery.rs (content)
⚔️ crates/biome_graphql_analyze/src/lint/nursery/use_input_name.rs (content)
⚔️ crates/biome_graphql_analyze/src/lint/style.rs (content)
⚔️ crates/biome_graphql_analyze/src/lint/suspicious.rs (content)
⚔️ crates/biome_graphql_formatter/Cargo.toml (content)
⚔️ crates/biome_graphql_parser/Cargo.toml (content)
⚔️ crates/biome_html_analyze/src/lint.rs (content)
⚔️ crates/biome_html_analyze/src/lint/a11y.rs (content)
⚔️ crates/biome_html_analyze/src/lint/a11y/no_redundant_alt.rs (content)
⚔️ crates/biome_html_analyze/src/lint/a11y/use_button_type.rs (content)
⚔️ crates/biome_html_analyze/src/lint/nursery.rs (content)
⚔️ crates/biome_html_analyze/src/options.rs (content)
⚔️ crates/biome_html_factory/src/generated/node_factory.rs (content)
⚔️ crates/biome_html_factory/src/generated/syntax_factory.rs (content)
⚔️ crates/biome_html_formatter/Cargo.toml (content)
⚔️ crates/biome_html_formatter/src/generated.rs (content)
⚔️ crates/biome_html_formatter/src/html/any/attribute.rs (content)
⚔️ crates/biome_html_formatter/src/html/any/attribute_initializer.rs (content)
⚔️ crates/biome_html_formatter/src/html/auxiliary/attribute.rs (content)
⚔️ crates/biome_html_formatter/src/html/auxiliary/attribute_initializer_clause.rs (content)
⚔️ crates/biome_html_formatter/src/html/auxiliary/mod.rs (content)
⚔️ crates/biome_html_formatter/src/html/lists/attribute_list.rs (content)
⚔️ crates/biome_html_formatter/src/utils/children.rs (content)
⚔️ crates/biome_html_formatter/tests/specs/html/interpolation/interpolation.html.snap (content)
⚔️ crates/biome_html_formatter/tests/specs/prettier/html/interpolation/example.html.snap (content)
⚔️ crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/hello-world.html.snap (content)
⚔️ crates/biome_html_parser/Cargo.toml (content)
⚔️ crates/biome_html_parser/src/syntax/mod.rs (content)
⚔️ crates/biome_html_parser/tests/html_specs/error/interpolation.html.snap (content)
⚔️ crates/biome_html_parser/tests/html_specs/ok/astro/attribute_expression.astro.snap (content)
⚔️ crates/biome_html_parser/tests/html_specs/ok/svelte/attach.svelte.snap (content)
⚔️ crates/biome_html_parser/tests/html_specs/ok/svelte/await_multiline.svelte.snap (content)
⚔️ crates/biome_html_parser/tests/html_specs/ok/svelte/complex_expressions.svelte.snap (content)
⚔️ crates/biome_html_parser/tests/html_specs/ok/svelte/dynamic-prop.svelte.snap (content)
⚔️ crates/biome_html_parser/tests/html_specs/ok/svelte/each_as_in_identifier.svelte.snap (content)
⚔️ crates/biome_html_parser/tests/html_specs/ok/svelte/shorthand-prop.svelte.snap (content)
⚔️ crates/biome_html_parser/tests/html_specs/ok/svelte/shorthand-spread-props.svelte.snap (content)
⚔️ crates/biome_html_parser/tests/spec_test.rs (content)
⚔️ crates/biome_html_syntax/src/attr_ext.rs (content)
⚔️ crates/biome_html_syntax/src/attribute_ext.rs (content)
⚔️ crates/biome_html_syntax/src/generated/kind.rs (content)
⚔️ crates/biome_html_syntax/src/generated/macros.rs (content)
⚔️ crates/biome_html_syntax/src/generated/nodes.rs (content)
⚔️ crates/biome_html_syntax/src/generated/nodes_mut.rs (content)
⚔️ crates/biome_js_analyze/Cargo.toml (content)
⚔️ crates/biome_js_analyze/src/assist.rs (content)
⚔️ crates/biome_js_analyze/src/assist/source.rs (content)
⚔️ crates/biome_js_analyze/src/assists.rs (content)
⚔️ crates/biome_js_analyze/src/lint.rs (content)
⚔️ crates/biome_js_analyze/src/lint/a11y.rs (content)
⚔️ crates/biome_js_analyze/src/lint/a11y/no_interactive_element_to_noninteractive_role.rs (content)
⚔️ crates/biome_js_analyze/src/lint/a11y/no_positive_tabindex.rs (content)
⚔️ crates/biome_js_analyze/src/lint/complexity.rs (content)
⚔️ crates/biome_js_analyze/src/lint/complexity/use_arrow_function.rs (content)
⚔️ crates/biome_js_analyze/src/lint/correctness.rs (content)
⚔️ crates/biome_js_analyze/src/lint/correctness/no_global_dirname_filename.rs (content)
⚔️ crates/biome_js_analyze/src/lint/correctness/no_unused_imports.rs (content)
⚔️ crates/biome_js_analyze/src/lint/correctness/use_exhaustive_dependencies.rs (content)
⚔️ crates/biome_js_analyze/src/lint/correctness/use_jsx_key_in_iterable.rs (content)
⚔️ crates/biome_js_analyze/src/lint/nursery.rs (content)
⚔️ crates/biome_js_analyze/src/lint/nursery/no_vue_arrow_func_in_watch.rs (content)
⚔️ crates/biome_js_analyze/src/lint/performance.rs (content)
⚔️ crates/biome_js_analyze/src/lint/security.rs (content)
⚔️ crates/biome_js_analyze/src/lint/style.rs (content)
⚔️ crates/biome_js_analyze/src/lint/style/no_common_js.rs (content)
⚔️ crates/biome_js_analyze/src/lint/style/use_consistent_type_definitions.rs (content)
⚔️ crates/biome_js_analyze/src/lint/style/use_naming_convention.rs (content)
⚔️ crates/biome_js_analyze/src/lint/suspicious.rs (content)
⚔️ crates/biome_js_analyze/src/lint/suspicious/no_assign_in_expressions.rs (content)
⚔️ crates/biome_js_analyze/src/lint/suspicious/use_await.rs (content)
⚔️ crates/biome_js_analyze/src/options.rs (content)
⚔️ crates/biome_js_analyze/src/react.rs (content)
⚔️ crates/biome_js_analyze/src/syntax.rs (content)
⚔️ crates/biome_js_analyze/src/syntax/correctness.rs (content)
⚔️ crates/biome_js_analyze/tests/specs/a11y/noInteractiveElementToNoninteractiveRole/valid.jsx (content)
⚔️ crates/biome_js_analyze/tests/specs/a11y/noInteractiveElementToNoninteractiveRole/valid.jsx.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/a11y/noPositiveTabindex/invalid.jsx.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/a11y/noPositiveTabindex/reactCreateElementInvalid.js.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/invalid-unused-react.jsx (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/invalid-unused-react.jsx.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/valid-unused-react.jsx (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/valid-unused-react.jsx.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/useExhaustiveDependencies/issue8802.ts (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/useExhaustiveDependencies/issue8802.ts.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/invalid.jsx (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/invalid.jsx.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx (content)
⚔️ crates/biome_js_analyze/tests/specs/correctness/useJsxKeyInIterable/valid.jsx.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/nursery/useAwaitThenable/valid.js (content)
⚔️ crates/biome_js_analyze/tests/specs/nursery/useAwaitThenable/valid.js.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/style/useConsistentTypeDefinitions/valid.ts (content)
⚔️ crates/biome_js_analyze/tests/specs/style/useConsistentTypeDefinitions/valid.ts.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/style/useImportType/valid-unused-react.tsx (content)
⚔️ crates/biome_js_analyze/tests/specs/style/useImportType/valid-unused-react.tsx.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/suspicious/noAssignInExpressions/invalid.js.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/suspicious/noAssignInExpressions/valid.js (content)
⚔️ crates/biome_js_analyze/tests/specs/suspicious/noAssignInExpressions/valid.js.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/suspicious/useAwait/invalid.js (content)
⚔️ crates/biome_js_analyze/tests/specs/suspicious/useAwait/invalid.js.snap (content)
⚔️ crates/biome_js_analyze/tests/specs/suspicious/useAwait/valid.js (content)
⚔️ crates/biome_js_analyze/tests/specs/suspicious/useAwait/valid.js.snap (content)
⚔️ crates/biome_js_formatter/Cargo.toml (content)
⚔️ crates/biome_js_formatter/src/utils/string_utils.rs (content)
⚔️ crates/biome_js_parser/Cargo.toml (content)
⚔️ crates/biome_js_type_info/src/type_data.rs (content)
⚔️ crates/biome_json_analyze/Cargo.toml (content)
⚔️ crates/biome_json_analyze/src/assist.rs (content)
⚔️ crates/biome_json_analyze/src/assist/source.rs (content)
⚔️ crates/biome_json_analyze/src/assists.rs (content)
⚔️ crates/biome_json_analyze/src/lint.rs (content)
⚔️ crates/biome_json_analyze/src/lint/nursery.rs (content)
⚔️ crates/biome_json_analyze/src/lint/suspicious.rs (content)
⚔️ crates/biome_json_analyze/src/registry.rs (content)
⚔️ crates/biome_json_formatter/Cargo.toml (content)
⚔️ crates/biome_json_parser/Cargo.toml (content)
⚔️ crates/biome_lsp/src/server.tests.rs (content)
⚔️ crates/biome_lsp/src/session.rs (content)
⚔️ crates/biome_rule_options/src/lib.rs (content)
⚔️ crates/biome_service/src/file_handlers/html.rs (content)
⚔️ crates/biome_service/src/workspace/server.rs (content)
⚔️ crates/biome_service/src/workspace/server.tests.rs (content)
⚔️ crates/biome_tailwind_parser/Cargo.toml (content)
⚔️ crates/biome_test_utils/Cargo.toml (content)
⚔️ crates/biome_test_utils/src/bench_case.rs (content)
⚔️ crates/biome_wasm/Cargo.toml (content)
⚔️ justfile (content)
⚔️ package.json (content)
⚔️ packages/@biomejs/backend-jsonrpc/CHANGELOG.md (content)
⚔️ packages/@biomejs/backend-jsonrpc/package.json (content)
⚔️ packages/@biomejs/backend-jsonrpc/src/workspace.ts (content)
⚔️ packages/@biomejs/biome/CHANGELOG.md (content)
⚔️ packages/@biomejs/biome/configuration_schema.json (content)
⚔️ packages/@biomejs/biome/package.json (content)
⚔️ packages/@biomejs/cli-darwin-arm64/CHANGELOG.md (content)
⚔️ packages/@biomejs/cli-darwin-arm64/package.json (content)
⚔️ packages/@biomejs/cli-darwin-x64/CHANGELOG.md (content)
⚔️ packages/@biomejs/cli-darwin-x64/package.json (content)
⚔️ packages/@biomejs/cli-linux-arm64-musl/CHANGELOG.md (content)
⚔️ packages/@biomejs/cli-linux-arm64-musl/package.json (content)
⚔️ packages/@biomejs/cli-linux-arm64/CHANGELOG.md (content)
⚔️ packages/@biomejs/cli-linux-arm64/package.json (content)
⚔️ packages/@biomejs/cli-linux-x64-musl/CHANGELOG.md (content)
⚔️ packages/@biomejs/cli-linux-x64-musl/package.json (content)
⚔️ packages/@biomejs/cli-linux-x64/CHANGELOG.md (content)
⚔️ packages/@biomejs/cli-linux-x64/package.json (content)
⚔️ packages/@biomejs/cli-win32-arm64/CHANGELOG.md (content)
⚔️ packages/@biomejs/cli-win32-arm64/package.json (content)
⚔️ packages/@biomejs/cli-win32-x64/CHANGELOG.md (content)
⚔️ packages/@biomejs/cli-win32-x64/package.json (content)
⚔️ packages/@biomejs/js-api/package.json (content)
⚔️ packages/@biomejs/wasm-bundler/CHANGELOG.md (content)
⚔️ packages/@biomejs/wasm-bundler/package.json (content)
⚔️ packages/@biomejs/wasm-nodejs/CHANGELOG.md (content)
⚔️ packages/@biomejs/wasm-nodejs/package.json (content)
⚔️ packages/@biomejs/wasm-web/CHANGELOG.md (content)
⚔️ packages/@biomejs/wasm-web/package.json (content)
⚔️ packages/aria-data/package.json (content)
⚔️ packages/prettier-compare/package.json (content)
⚔️ pnpm-lock.yaml (content)
⚔️ xtask/codegen/html.ungram (content)
⚔️ xtask/codegen/src/html_kinds_src.rs (content)
⚔️ xtask/glue/src/lib.rs (content)

These conflicts must be resolved before merging into next.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main fix: preventing duplicate trivia (whitespace) when updating snippets in the service layer.
Description check ✅ Passed The description provides a clear explanation of the bug, its root cause, and references the linked issue #9050, demonstrating direct relation to the changeset.
Linked Issues check ✅ Passed The PR directly addresses #9050 by fixing the root cause: trimming new_code in update_snippets to prevent duplicated trivia when updating embedded snippets.
Out of Scope Changes check ✅ Passed All changes are in-scope: the HTML handler fix targets the trivia duplication issue, and the new test validates the fix for embedded Vue snippet newline handling.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dyc3/fix-duplicated-trivia-embedded-snippets
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch dyc3/fix-duplicated-trivia-embedded-snippets
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

No actionable comments were generated in the recent review. 🎉


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

Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

Awesome! Good catch, that part isn't easy to handle

@dyc3 dyc3 merged commit 5483570 into next Feb 13, 2026
6 of 11 checks passed
@dyc3 dyc3 deleted the dyc3/fix-duplicated-trivia-embedded-snippets branch February 13, 2026 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Project Area: project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants