Skip to content

Conversation

@dyc3
Copy link
Contributor

@dyc3 dyc3 commented Dec 15, 2025

Summary

This fixes a regression that was introduced in today's release (2.3.9).

fixes #8475

Test Plan

snapshots

Docs

@changeset-bot
Copy link

changeset-bot bot commented Dec 15, 2025

🦋 Changeset detected

Latest commit: e1dcffd

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 15, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 15, 2025

Walkthrough

Adjusts the nesting-detection logic in the suspicious/noExtraNonNullAssertion lint: when encountering a TsNonNullAssertionExpression, the code now inspects only the first non-parenthesized ancestor and returns immediately if that ancestor is also a TsNonNullAssertionExpression. The previous scan of all non-parenthesized ancestors was removed. Adds test cases (valid and invalid) covering nested and parenthesised non-null assertion patterns and a changelog entry.

Possibly related PRs

Suggested reviewers

  • ematipico

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the core change: fixing a regression in the noExtraNonNullAssertion rule.
Description check ✅ Passed The description is directly related to the changeset, explaining the regression fix and referencing issue #8475 that the PR addresses.
Linked Issues check ✅ Passed The code changes align with issue #8475 requirements: modifying nesting detection logic to avoid false positives on chained non-null assertions, and adding test cases covering the reported scenarios.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the regression: rule logic update, changeset addition, and test case extensions directly address issue #8475.
✨ 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 fix-extra-non-nulls-regression

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 (3)
.changeset/full-dancers-repeat.md (1)

5-5: Enhance the changeset per guidelines.

The description is missing a period at the end and could benefit from a code example. As per coding guidelines, changesets for rules should include code examples.

Consider this revision:

-Fixed [#8475](https://github.com/biomejs/biome/issues/8475): fixed a regression in how `noExtraNonNullAssertion` flags extra non-null assertions
+Fixed [#8475](https://github.com/biomejs/biome/issues/8475): `noExtraNonNullAssertion` now correctly allows chained non-null assertions like `blob.b!.d!.length` whilst still catching nested ones like `(blob.b!)!`.
crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/invalid.ts (1)

58-59: Variable redeclaration in test cases.

Both test cases declare _d2, which would normally trigger a TypeScript redeclaration error. Whilst this is likely intentional for a lint-only test file, consider using distinct names (e.g., _d2_paren1, _d2_paren2) for clarity.

crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts (1)

28-29: Variable redeclaration in test cases.

Both test cases declare _d2, mirroring the naming pattern in invalid.ts. Whilst acceptable for lint tests, distinct names (e.g., _d2_chained, _d2_optional) would improve clarity.

📜 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 285d932 and 2177142.

⛔ Files ignored due to path filters (2)
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (4)
  • .changeset/full-dancers-repeat.md (1 hunks)
  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/invalid.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts (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/full-dancers-repeat.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/suspicious/no_extra_non_null_assertion.rs
🧠 Learnings (15)
📓 Common learnings
Learnt from: arendjr
Repo: biomejs/biome PR: 7593
File: crates/biome_service/src/workspace/server.rs:1306-1306
Timestamp: 2025-09-25T12:32:59.003Z
Learning: In the biomejs/biome project, do not flag compilation errors during code review as they are handled by the existing test infrastructure and CI. Focus on other code quality aspects instead.
📚 Learning: 2025-09-25T12:32:59.003Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7593
File: crates/biome_service/src/workspace/server.rs:1306-1306
Timestamp: 2025-09-25T12:32:59.003Z
Learning: In the biomejs/biome project, do not flag compilation errors during code review as they are handled by the existing test infrastructure and CI. Focus on other code quality aspects instead.

Applied to files:

  • .changeset/full-dancers-repeat.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/**/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/suspicious/noExtraNonNullAssertion/invalid.ts
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts
📚 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/suspicious/noExtraNonNullAssertion/invalid.ts
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts
📚 Learning: 2025-12-04T13:29:49.287Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8291
File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10
Timestamp: 2025-12-04T13:29:49.287Z
Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.

Applied to files:

  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts
📚 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/suspicious/no_extra_non_null_assertion.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 `noRedundant` prefix for rules that report redundant code (e.g., `noRedundantUseStrict`)

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.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 `noExcessive` prefix for rules that report code exceeding configurable limits (e.g., `noExcessiveNestedTestSuites`)

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.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 `noUnused` prefix for rules that report unused entities (e.g., `noUnusedVariables`)

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.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/suspicious/no_extra_non_null_assertion.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 `noEmpty` prefix for rules that report empty code (e.g., `noEmptyBlockStatements`)

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.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/suspicious/no_extra_non_null_assertion.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 `noUseless` prefix for rules that report unnecessary code that could be removed or simplified (e.g., `noUselessConstructor`)

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.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 : Avoid unnecessary string allocations by comparing against `&str` or `TokenText` instead of calling `to_string()` which allocates heap memory

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.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 : Avoid using `unwrap()` or `expect()` on `Result` and `Option` types; instead use helper functions like `map`, `filter`, `and_then` to maintain code clarity and avoid panics

Applied to files:

  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: End-to-end tests
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: autofix
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_parser)
🔇 Additional comments (1)
crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.rs (1)

87-99: Elegant fix for the regression.

The short-circuit logic correctly distinguishes chained assertions (blob.b!.d!.length) from genuinely nested ones ((blob.b!)!) by examining only the immediate non-parenthesised ancestor. The comment on line 92 helpfully clarifies intent.

@dyc3 dyc3 force-pushed the fix-extra-non-nulls-regression branch from 2177142 to e1dcffd Compare December 15, 2025 21:25
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: 1

📜 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 2177142 and e1dcffd.

⛔ Files ignored due to path filters (2)
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (4)
  • .changeset/full-dancers-repeat.md (1 hunks)
  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/invalid.ts (1 hunks)
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/invalid.ts
  • crates/biome_js_analyze/src/lint/suspicious/no_extra_non_null_assertion.rs
🧰 Additional context used
📓 Path-based instructions (1)
.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/full-dancers-repeat.md
🧠 Learnings (4)
📚 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/suspicious/noExtraNonNullAssertion/valid.ts
📚 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/suspicious/noExtraNonNullAssertion/valid.ts
📚 Learning: 2025-12-04T13:29:49.287Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8291
File: crates/biome_html_formatter/tests/specs/prettier/vue/html-vue/elastic-header.html:10-10
Timestamp: 2025-12-04T13:29:49.287Z
Learning: Files under `crates/biome_html_formatter/tests/specs/prettier` are test fixtures synced from Prettier and should not receive detailed code quality reviews (e.g., HTTP vs HTTPS, formatting suggestions, etc.). These files are test data meant to validate formatter behavior and should be preserved as-is.

Applied to files:

  • crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts
📚 Learning: 2025-09-25T12:32:59.003Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7593
File: crates/biome_service/src/workspace/server.rs:1306-1306
Timestamp: 2025-09-25T12:32:59.003Z
Learning: In the biomejs/biome project, do not flag compilation errors during code review as they are handled by the existing test infrastructure and CI. Focus on other code quality aspects instead.

Applied to files:

  • .changeset/full-dancers-repeat.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: Test Node.js API
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Validate rules documentation
  • GitHub Check: autofix
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
🔇 Additional comments (1)
crates/biome_js_analyze/tests/specs/suspicious/noExtraNonNullAssertion/valid.ts (1)

26-29: Proper test coverage for the regression.

These cases correctly validate that chained non-null assertions (blob.b!.d!.length) and optional chaining with non-null (blob.b?.d!.length) are not incorrectly flagged by the rule.

"@biomejs/biome": patch
---

Fixed [#8475](https://github.com/biomejs/biome/issues/8475): fixed a regression in how `noExtraNonNullAssertion` flags extra non-null assertions
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add a code example and simplify wording.

The changeset guidelines require code examples for rule changes. Consider showing what's now correctly handled (e.g., blob.b!.d!.length). Also, "Fixed ... fixed" reads redundantly.

Apply this diff:

-Fixed [#8475](https://github.com/biomejs/biome/issues/8475): fixed a regression in how `noExtraNonNullAssertion` flags extra non-null assertions
+Fixed [#8475](https://github.com/biomejs/biome/issues/8475). The rule `noExtraNonNullAssertion` now correctly handles chained non-null assertions like `blob.b!.d!.length`.

Based on coding guidelines for changesets.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Fixed [#8475](https://github.com/biomejs/biome/issues/8475): fixed a regression in how `noExtraNonNullAssertion` flags extra non-null assertions
Fixed [#8475](https://github.com/biomejs/biome/issues/8475). The rule `noExtraNonNullAssertion` now correctly handles chained non-null assertions like `blob.b!.d!.length`.
🤖 Prompt for AI Agents
In .changeset/full-dancers-repeat.md around line 5, the changeset message is
redundant ("Fixed ... fixed") and lacks the required code example for the rule
change; update the text to remove the duplicate wording (e.g., start with "Fix:
regression in how `noExtraNonNullAssertion` flags extra non-null assertions")
and add a brief code example showing the corrected behavior (for example
illustrate allowed/flagged cases such as blob.b!.d!.length). Keep the wording
concise and follow changeset guidelines by including the example and a single
clear sentence describing the fix.

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 15, 2025

CodSpeed Performance Report

Merging #8477 will not alter performance

Comparing fix-extra-non-nulls-regression (e1dcffd) with main (285d932)1

Summary

✅ 58 untouched
⏩ 95 skipped2

Footnotes

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

  2. 95 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 90e8684 into main Dec 15, 2025
18 checks passed
@dyc3 dyc3 deleted the fix-extra-non-nulls-regression branch December 15, 2025 21:43
@github-actions github-actions bot mentioned this pull request Dec 15, 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.

💅 New false positive for extra non null assertion in v2.3.9

3 participants