Skip to content

fix(lint): noArrayIndexKey should flag index anywhere in template#8968

Merged
dyc3 merged 4 commits intobiomejs:mainfrom
LouisLau-art:fix/noArrayIndexKey-template-order
Feb 28, 2026
Merged

fix(lint): noArrayIndexKey should flag index anywhere in template#8968
dyc3 merged 4 commits intobiomejs:mainfrom
LouisLau-art:fix/noArrayIndexKey-template-order

Conversation

@LouisLau-art
Copy link
Contributor

@LouisLau-art LouisLau-art commented Feb 5, 2026

Summary

Fixes #8812.

lint/suspicious/noArrayIndexKey previously only tracked the last identifier found in a template/binary expression (and could skip reporting when templates mixed identifier and non-identifier expressions).

This update collects all reference identifiers from key expressions (template, binary, parenthesized) and reports when any of them resolves to the array-index parameter.

Added test coverage for cases like:

  • key={`${index}-${item}`}
  • key={`${item.title}-${index}`}
  • key={index + item}

AI assistance notice: this PR was prepared with AI assistance and manually verified before submission.

Test Plan

  • cargo test -p biome_js_analyze -- no_array_index_key
  • cargo test -p biome_js_formatter

Docs

No docs change required; this is a behavior fix for an existing lint rule.

@changeset-bot
Copy link

changeset-bot bot commented Feb 5, 2026

🦋 Changeset detected

Latest commit: eee9cf9

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 5, 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 399cb54 and eee9cf9.

📒 Files selected for processing (1)
  • .changeset/no-array-index-key-template-order.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/no-array-index-key-template-order.md

Walkthrough

Reworks the noArrayIndexKey lint to gather multiple candidate identifiers from key expressions (identifiers, template literals, binary expressions, parenthesised expressions) via a new collect_reference_identifiers routine. Each candidate is resolved to a function parameter and traced to its containing call expression to check whether it represents an array index (is_array_method_index). Retains the React.cloneElement diagnostic path, removes the previous recursive cap_array_index_value traversal, simplifies control flow with early continues, and adds tests covering template and binary key expressions that include the index. Adds a changelog entry for the fix.

Suggested reviewers

  • ematipico
  • Netail
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main fix: the noArrayIndexKey lint rule now flags index usage anywhere in templates, not just the last position.
Description check ✅ Passed The description clearly explains the fix, references issue #8812, and outlines the test coverage and approach taken.
Linked Issues check ✅ Passed The changes fully address issue #8812 by collecting all reference identifiers from key expressions and detecting array-index usage anywhere in templates or binary expressions.
Out of Scope Changes check ✅ Passed All changes are tightly scoped to fixing noArrayIndexKey detection: updated rule logic, expanded test cases, and added changelog entry.

✏️ 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

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.

@dyc3
Copy link
Contributor

dyc3 commented Feb 6, 2026

Please add a changeset and restore our PR template

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 6, 2026

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 95 skipped benchmarks1


Comparing LouisLau-art:fix/noArrayIndexKey-template-order (eee9cf9) with main (db0da5c)

Open in CodSpeed

Footnotes

  1. 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.

@LouisLau-art
Copy link
Contributor Author

Thanks for the reminder. I’ll add a changeset and restore the PR template format in this PR.

@LouisLau-art
Copy link
Contributor Author

Addressed both points: I added a changeset in this branch and restored the PR description structure using the project PR template sections (Summary/Test Plan/Docs).

Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

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

Looks good. Just fix the lints from clippy

@LouisLau-art
Copy link
Contributor Author

Thanks, I’ll take care of the remaining Clippy lints in a follow-up commit.

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 `@crates/biome_js_analyze/src/lint/suspicious/no_array_index_key.rs`:
- Around line 175-176: The code currently uses the `?` operator on
`is_array_method_index(&parameter, &call_expression)` inside `run`, which causes
`run` to return early when that helper yields `None` (non-array contexts) and
skips later candidates; change this to explicitly handle the Option: call
`is_array_method_index(&parameter, &call_expression)` and `match`/`if let
Some(is_index) = ...` (or `if let None = ... { continue; }`) and only bail out
when it returns `Some(false)`/`true` per your logic, otherwise `continue` to the
next candidate so non-array contexts do not abort the whole analysis. Ensure you
update the branch around the current `if !is_array_method_index(...)? {
continue; }` to use this explicit handling.

ℹ️ 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 93789c6 and 399cb54.

📒 Files selected for processing (1)
  • crates/biome_js_analyze/src/lint/suspicious/no_array_index_key.rs

Comment on lines +175 to +176
if !is_array_method_index(&parameter, &call_expression)? {
continue;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid bailing out the whole analysis on non-array candidates.

At Line 175, is_array_method_index(...)? returns None for non-array call contexts and exits run early, so later candidates in the same key expression are never checked. That can still miss a real index reference.

Suggested fix
-            if !is_array_method_index(&parameter, &call_expression)? {
-                continue;
-            }
+            let Some(is_index_parameter) = is_array_method_index(&parameter, &call_expression)
+            else {
+                continue;
+            };
+            if !is_index_parameter {
+                continue;
+            }
📝 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
if !is_array_method_index(&parameter, &call_expression)? {
continue;
let Some(is_index_parameter) = is_array_method_index(&parameter, &call_expression)
else {
continue;
};
if !is_index_parameter {
continue;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_js_analyze/src/lint/suspicious/no_array_index_key.rs` around
lines 175 - 176, The code currently uses the `?` operator on
`is_array_method_index(&parameter, &call_expression)` inside `run`, which causes
`run` to return early when that helper yields `None` (non-array contexts) and
skips later candidates; change this to explicitly handle the Option: call
`is_array_method_index(&parameter, &call_expression)` and `match`/`if let
Some(is_index) = ...` (or `if let None = ... { continue; }`) and only bail out
when it returns `Some(false)`/`true` per your logic, otherwise `continue` to the
next candidate so non-array contexts do not abort the whole analysis. Ensure you
update the branch around the current `if !is_array_method_index(...)? {
continue; }` to use this explicit handling.

@dyc3 dyc3 merged commit a2b4494 into biomejs:main Feb 28, 2026
18 checks passed
@github-actions github-actions bot mentioned this pull request Feb 28, 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-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💅 lint/suspicious/noArrayIndexKey false negative when re-ordering value and index in template string

2 participants