Skip to content

fix(analyzer): some rules panicked#9255

Merged
ematipico merged 2 commits intomainfrom
fix/nursery-rule
Feb 27, 2026
Merged

fix(analyzer): some rules panicked#9255
ematipico merged 2 commits intomainfrom
fix/nursery-rule

Conversation

@ematipico
Copy link
Member

Summary

Closes #9234

We really should pay attention to type Options = (). That breaks with a panic. There were a bunch of rule that didn't have that.

We could improve the rules-check harnes, but not in this PR

Test Plan

Tested manually using OPs reproduction

Docs

@changeset-bot
Copy link

changeset-bot bot commented Feb 26, 2026

🦋 Changeset detected

Latest commit: 10b8b21

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

@ematipico ematipico requested review from a team February 26, 2026 23:11
@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages L-HTML Language: HTML and super languages labels Feb 26, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ea4c16 and 10b8b21.

📒 Files selected for processing (1)
  • .changeset/ninety-wombats-run.md

Walkthrough

Adds a changeset file for a patch release addressing issue #9234 and updates several lint rule implementations to use concrete options structs instead of the unit type (). Affected rules: NoHeaderScope, NoPositiveTabindex, UseAnchorContent, UseMediaCaption, NoVueSetupPropsReactivityLoss, NoMisusedPromises and NoParametersOnlyUsedInRecursion — each now declares a dedicated *Options associated type. No behavioural logic changes were introduced in the rule run/diagnostic paths.

Possibly related PRs

Suggested labels

A-Core, A-CLI

Suggested reviewers

  • dyc3
  • siketyan
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: fixing a panic in several analyzer rules caused by improper handling of empty Options types.
Description check ✅ Passed The description clearly relates to the changeset, explaining the root cause (type Options = ()) and that multiple rules lacked proper handling for it.
Linked Issues check ✅ Passed Changes directly address issue #9234 by converting affected rules from empty tuple Options to their respective Options structs, resolving the unwrap() panic.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the panic by updating rule Options types in HTML and JS analyzers, with no extraneous modifications.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/nursery-rule

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: 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/ninety-wombats-run.md:
- Line 5: The release note in .changeset/ninety-wombats-run.md contains a
truncated word "optio." — edit that line to replace "optio." with the full word
"option." (and ensure the sentence reads correctly: "configured with the option
`level` without the option."). If the sentence was meant to continue, complete
it sensibly (e.g., "configured with the option `level` without the option
`...`") so the changelog is not cut off or ambiguous.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d0b8e6 and 7ea4c16.

📒 Files selected for processing (8)
  • .changeset/ninety-wombats-run.md
  • crates/biome_html_analyze/src/lint/a11y/no_header_scope.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
  • crates/biome_html_analyze/src/lint/a11y/use_anchor_content.rs
  • crates/biome_html_analyze/src/lint/a11y/use_media_caption.rs
  • crates/biome_js_analyze/src/lint/correctness/no_vue_setup_props_reactivity_loss.rs
  • crates/biome_js_analyze/src/lint/nursery/no_misused_promises.rs
  • crates/biome_js_analyze/src/lint/nursery/no_parameters_only_used_in_recursion.rs

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@codspeed-hq
Copy link

codspeed-hq bot commented Feb 26, 2026

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 156 skipped benchmarks1


Comparing fix/nursery-rule (10b8b21) with main (2d0b8e6)

Open in CodSpeed

Footnotes

  1. 156 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
Copy link
Contributor

dyc3 commented Feb 27, 2026

@coderabbitai open an issue to improve our rules check harness to forbid lint rules from having no options type (type Options = () not allowed)

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@dyc3, I'll create an issue to track improving the rules check harness.


🏁 Script executed:

#!/bin/bash
# Create GitHub issue to improve rules check harness
gh issue create \
  --title "Improve rules check harness to forbid \`type Options = ()\`" \
  --body "## Context

PR `#9255` fixed a panic (reported in `#9234`) that occurred when lint rules declared their options type as \`type Options = ()\` instead of using the generated options struct (e.g., \`NoHeaderScopeOptions\`).

## Problem

Currently, the rules check harness does not validate that lint rules use proper options types. When rules use \`type Options = ()\`, it can lead to \`Option::unwrap()\` panics in \`biome_analyze/src/options.rs\`.

## Proposed Solution

Enhance the rules check harness to forbid lint rules from declaring \`type Options = ()\`. All rules should use their generated options types (e.g., \`RuleNameOptions\`), even if the struct is empty.

## References

- Fixed in: `#9255`
- Original panic report: `#9234`" \
  --assignee dyc3

Length of output: 44


@dyc3, I've opened issue #9263 to track improving the rules check harness to forbid type Options = (). The issue includes context from this PR and references to #9234.


🧠 Learnings used
Learnt from: dyc3
Repo: biomejs/biome PR: 8171
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:125-137
Timestamp: 2025-11-21T01:10:53.059Z
Learning: In the Biome codebase, each lint rule has its own options type declaration (e.g., `type Options = RuleNameOptions`) as part of the codegen process, even if the options struct is empty or unused. This is standard practice and should not be flagged as an issue.

Learnt from: dyc3
Repo: biomejs/biome PR: 8639
File: crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs:101-108
Timestamp: 2025-12-31T15:35:41.261Z
Learning: In crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs, the `issue_number` field in `declare_lint_rule!` macro is optional and the vast majority of nursery rules do not need it. Do not recommend adding `issue_number` unless there's a specific reason.

Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T21:15:03.796Z
Learning: For new lint rules in changesets, show an example of invalid case in inline code or code block

Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:27:13.161Z
Learning: In crates/biome_analyze/**/*analyze/src/**/*.rs, the `fix_kind` field in `declare_lint_rule!` should only be specified when the rule implements the `action` function. Rules that only emit diagnostics without providing code fixes should not include `fix_kind` in their metadata.

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-17T19:45:06.423Z
Learning: Applies to crates/biome_analyze/**/*.rs : Lint rules must follow the naming convention: use `no<Concept>` prefix when forbidding a single concept (e.g., `noDebugger`), and `use<Concept>` prefix when mandating a single concept (e.g., `useValidLang`)

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-17T19:45:06.423Z
Learning: Applies to crates/biome_analyze/**/*.rs : Mark rules as work-in-progress by adding `issue_number` field to the `declare_lint_rule!` macro, which adds a footnote to diagnostics and a note on the website with a link to the GitHub issue

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-17T19:45:06.423Z
Learning: Applies to crates/biome_analyze/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rules with required metadata: `version` (set to 'next'), `name` (the rule identifier), `language` (e.g., 'js', 'jsx', 'ts', 'tsx'), and optional `recommended`, `severity`, `fix_kind`, `sources`, `domains`, `deprecated`, and `issue_number` fields

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-17T19:45:06.423Z
Learning: Applies to crates/biome_analyze/**/*.rs : Choose rule severity based on error type: `error` for hard errors/dangerous/accessibility issues, `warn` for possibly erroneous code, `info` for stylistic suggestions. Correctness/security/a11y rules must be `error`, style rules must be `info` or `warn`, complexity rules must be `warn` or `info`

Learnt from: CR
Repo: biomejs/biome PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-02-14T16:38:40.471Z
Learning: Applies to **/*_analyze/**/*.rs : Run `just gen-rules` and `just gen-configuration` before opening a PR when implementing changes to lint rules in `*_analyze` directories

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-17T19:45:06.423Z
Learning: Applies to crates/biome_analyze/**/*.rs : For code actions, implement the `action` function and add `fix_kind` metadata (`FixKind::Safe` or `FixKind::Unsafe`). Return a `JsRuleAction` with mutation, category, applicability, and message

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-17T19:45:06.423Z
Learning: Applies to crates/biome_analyze/**/*.rs : New rules must be placed in the `nursery` group as an incubation space exempt from semantic versioning, and can be promoted to appropriate groups in minor/major releases

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-17T19:45:06.423Z
Learning: Applies to crates/biome_analyze/**/*.rs : For rules derived from other linters, use the `sources` metadata with `RuleSource::Eslint` and either `.same()` for identical behavior or `.inspired()` for different behavior/options

Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2026-01-17T19:45:06.423Z
Learning: Applies to crates/biome_analyze/**/*.rs : Document rules with a single-line first paragraph (used as brief description), followed by `## Examples` section with `### Invalid` and `### Valid` subsections, and optionally `## Options` section documenting each option

@ematipico ematipico merged commit 9b6685b into main Feb 27, 2026
21 checks passed
@ematipico ematipico deleted the fix/nursery-rule branch February 27, 2026 16:01
@github-actions github-actions bot mentioned this pull request Feb 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 processing panicked: called Option::unwrap() on a None value

2 participants