Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@tt-a1i
Copy link
Contributor

@tt-a1i tt-a1i commented Dec 13, 2025

Summary

This PR fixes #8011 where useConsistentCurlyBraces would suggest removing curly braces from JSX expression children containing characters that would cause parsing issues or semantic changes when converted to plain JSX text.

Changes

Added forbidden characters check to FORBIDDEN_CHARS in use_consistent_curly_braces.rs with detailed doc comments explaining the rationale.

Characters that cause issues when converted from JSX expression to plain JSX text:

  • { } - would be parsed as expression delimiters
  • < > - would be parsed as tag delimiters
  • & - would be parsed as HTML entity start
  • " ' - included for consistency

Scope: This guard applies only to JSX children (not attributes), because attribute strings have different parsing rules where these characters are safe.

Before this fix:

// Input
<Foo>{"start {{"}</Foo>
<Foo>{"<script>"}</Foo>
<Foo>{"Tom & Jerry"}</Foo>

// After unsafe fix (invalid/different JSX!)
<Foo>start {{</Foo>      // syntax error - { starts expression
<Foo><script></Foo>      // becomes an actual script tag!
<Foo>Tom & Jerry</Foo>   // & might be interpreted as entity start

After this fix, the rule correctly leaves these strings alone.

Test Plan

  • Added test cases for {, <, & in valid.jsx
  • Ran cargo test -p biome_js_analyze use_consistent_curly_braces - all tests pass

AI Assistance Disclosure

This PR was written with assistance from Claude Code.

@changeset-bot
Copy link

changeset-bot bot commented Dec 13, 2025

🦋 Changeset detected

Latest commit: e943457

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 added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Dec 13, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 13, 2025

Walkthrough

The PR updates the useConsistentCurlyBraces lint to avoid suggesting removal of JSX curly braces when the contained string literal includes characters that cannot appear unescaped in JSX text (forbidden characters: {, }, <, >, &, " and '). It adds a changeset entry for a patch release and new tests covering edge cases that previously produced invalid or semantically altered JSX, addressing issue #8011.

Possibly related PRs

Suggested reviewers

  • ematipico
  • siketyan

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed Description clearly explains the issue, the fix (forbidden characters check), examples of problematic transformations, and test coverage.
Linked Issues check ✅ Passed PR fully addresses issue #8011 by expanding FORBIDDEN_CHARS and updating the rule logic to prevent unsafe JSX transformations for strings containing {, }, <, >, &, ", and '.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing issue #8011: the changeset entry, the rule implementation, and test cases for the forbidden character fix.
Title check ✅ Passed The title accurately describes the main fix: preventing useConsistentCurlyBraces from suggesting invalid JSX text conversions when encountering forbidden characters.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
.changeset/fix-curly-braces-opening-brace.md (1)

1-5: Add a code example to the changeset.

As per coding guidelines, changesets for rule changes should include code examples. Consider adding a brief before/after snippet, e.g.:

Before: `<Foo>{'start {{'}</Foo>` → invalid `<Foo>start {{</Foo>`  
After: braces are preserved when strings contain `{`

Based on coding guidelines, changesets should include code examples for rules.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f7171a and 53b6593.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/style/useConsistentCurlyBraces/valid.jsx.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (3)
  • .changeset/fix-curly-braces-opening-brace.md (1 hunks)
  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/style/useConsistentCurlyBraces/valid.jsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Write changesets that are concise (1-3 sentences), user-focused, use past tense for actions taken and present tense for Biome behavior, include code examples for rules, and end sentences with periods

Files:

  • .changeset/fix-curly-braces-opening-brace.md
crates/**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update inline rustdoc documentation for rules, assists, and their options when adding new features or changing existing features in Rust crates

Files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use language tags in documentation code blocks (js, ts, tsx, json, css) and order properties consistently as: language, then `expect_diagnostic`, then options modifiers, then `ignore`, then `file=path`
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnsafe` prefix for rules that report code leading to runtime failures (e.g., `noUnsafeOptionalChaining`)
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Code actions must specify a `fix_kind` field in the `declare_lint_rule!` macro as either `FixKind::Safe` or `FixKind::Unsafe` to indicate whether fixes always preserve program behavior
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noInvalid` prefix for rules that report runtime errors from mistyping (e.g., `noInvalidConstructorSuper`)
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/*.{js,ts,tsx,jsx,json,css} : Test rules using snapshot tests via the `insta` library with test cases in `tests/specs/<group>/<rule_name>/` directories prefixed by `invalid` or `valid`

Applied to files:

  • crates/biome_js_analyze/tests/specs/style/useConsistentCurlyBraces/valid.jsx
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/tests/specs/**/*.jsonc : Use `.jsonc` files in test specs with code snippets as array of strings to test rules in script environment (no import/export syntax)

Applied to files:

  • crates/biome_js_analyze/tests/specs/style/useConsistentCurlyBraces/valid.jsx
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Commit rule changes with message format: `feat(biome_<crate>): <ruleName>` to follow Biome's conventional commit style

Applied to files:

  • .changeset/fix-curly-braces-opening-brace.md
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noRestricted` prefix for rules that report user-banned entities (e.g., `noRestrictedGlobals`)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Framework-specific rules should be named using the `use` or `no` prefix followed by the framework name (e.g., `noVueReservedProps`)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use language tags in documentation code blocks (js, ts, tsx, json, css) and order properties consistently as: language, then `expect_diagnostic`, then options modifiers, then `ignore`, then `file=path`

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `useConsistent` prefix for rules that ensure consistency across the codebase (e.g., `useConsistentArrayType`)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Check if a variable is global before banning it to avoid false positives when the variable is redeclared in local scope; use the semantic model to verify global scope

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnknown` prefix for rules that report mistyped entities in CSS (e.g., `noUnknownUnit`)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUndeclared` prefix for rules that report undefined entities (e.g., `noUndeclaredVariables`)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnsafe` prefix for rules that report code leading to runtime failures (e.g., `noUnsafeOptionalChaining`)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Rules should use the `use` prefix naming convention when the sole intention is to mandate a single concept (e.g., `useValidLang` to enforce valid HTML lang attribute values)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noInvalid` prefix for rules that report runtime errors from mistyping (e.g., `noInvalidConstructorSuper`)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs
🔇 Additional comments (2)
crates/biome_js_analyze/src/lint/style/use_consistent_curly_braces.rs (1)

413-413: LGTM! Elegant fix.

Adding { to the forbidden characters correctly prevents the rule from suggesting invalid transformations. The logic is sound: strings containing { now skip the "remove braces" diagnostic, avoiding broken JSX like <Foo>start {{</Foo>.

crates/biome_js_analyze/tests/specs/style/useConsistentCurlyBraces/valid.jsx (1)

31-38: Solid test coverage.

These cases properly validate that the rule doesn't flag expressions containing { or }}, directly addressing the scenarios from issue #8011.

@tt-a1i tt-a1i force-pushed the fix/use-consistent-curly-braces-escape-braces branch 2 times, most recently from 410f214 to 3a342c8 Compare December 13, 2025 15:14
Add '{', '<', and '&' to FORBIDDEN_CHARS to prevent the rule from suggesting
to remove curly braces from strings containing characters that cannot appear
unescaped in JSX text, which would produce invalid or semantically different JSX.

Fixes biomejs#8011
@tt-a1i tt-a1i force-pushed the fix/use-consistent-curly-braces-escape-braces branch from 3a342c8 to e943457 Compare December 13, 2025 15:20
@tt-a1i tt-a1i changed the title fix(linter): prevent useConsistentCurlyBraces from producing invalid JSX fix(linter): prevent useConsistentCurlyBraces from suggesting invalid JSX text conversion Dec 13, 2025
@codspeed-hq
Copy link

codspeed-hq bot commented Dec 13, 2025

CodSpeed Performance Report

Merging #8439 will not alter performance

Comparing tt-a1i:fix/use-consistent-curly-braces-escape-braces (e943457) with main (382786b)1

Summary

✅ 56 untouched
⏩ 97 skipped2

Footnotes

  1. No successful run was found on main (0f7171a) during the generation of this report, so 382786b was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

  2. 97 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.

@dyc3 dyc3 merged commit a78774b into biomejs:main Dec 13, 2025
20 checks passed
This was referenced Dec 13, 2025
l0ngvh pushed a commit to l0ngvh/biome that referenced this pull request Dec 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useConsistentCurlyBraces suggests invalid JSX

2 participants