biome style/noUselessElse: fixed output does not parse
Hypothesis Nemotron 3 Super predicted to fire fired 1×
name collisions across scopes after a move (shadowing)
Program
Output
(no stdout)
(no stdout)
- fired
- 1 before · 0 after
- runs
- each version twice, same file name, no network
Judge Nemotron 3 Ultra advisory real · high
The fix hoists the `let x = 2` declaration out of the `else` block into the same scope where `let x = 1` already exists, causing a duplicate declaration SyntaxError. The documentation presents the rewrite as equivalent but does not account for block-scoped declarations that would collide when moved outward.
Explanation Nemotron 3 Super unverified
The original code declares `x` in two separate scopes: one in the outer block (`let x = 1`) and another inside the `else` block (`let x = 2`). These are distinct variables due to lexical scoping. Removing the `else` keyword merges both declarations into the same scope—the function body—causing a duplicate declaration of `x`, which is invalid syntax. Thus, the transformation breaks correctness by violating JavaScript’s block-scoped variable rules, making the rewritten program fail to parse.
Reproduce
- file
prog.js(the before program)- minimized program
- r2-p001.js
- evidence sheet
- r2-p001.md
- regression fixture
- r2-p001.js the minimized program with a header stating the observed change, for the tool's test suite
node prog.js bunx @biomejs/biome lint --only=style/noUselessElse --write prog.js node prog.js
Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra
noUselessElse fix · style noUselessElse block-scoped variable · if-else redundant branch declaration conflict · useless else shadowing outer scope
- duplicate biomejs/biome/issues/11937 same rule noUselessElse removing an else block that contains a let declaration colliding with an outer let x
- related biomejs/biome/issues/11351 same class of defect safe fix breaking code but different rule useSimplifiedLogicExpression
- related biomejs/biome/issues/11558 same class of defect broken fix but different rule useExplicitLengthCheck
- related biomejs/biome/issues/11092 same rule noUselessElse but different defect double space in quick fix not declaration collision
- related biomejs/biome/issues/8347 same class of defect corrupted safe fix but different rule useConsistentArrowReturn
- related biomejs/biome/issues/3770 same rule noUselessElse but different construct else with break in loop not declaration collision
- related biomejs/biome/issues/1191 same rule noUselessElse but different construct else if with ObjectPattern not declaration collision
Details
- program
- Shadowing after removal of else block
- hazard
- name collisions across scopes after a move (shadowing)
- oracle
/home/sun/dev/diaghunt/runs/2026-10-17T19-42-12-619Z-e4vp-biome-style_noUselessElse/r2-p001/min/r2-p001-reuse/fixed.js:5 let x = 2; ^ SyntaxError: Identifier 'x' has already been declared at checkSyntax (node:internal/main/check_syntax:84:5) Node.js v26.8.1- run
- 2026-10-17T19-42-12-619Z-e4vp-biome-style_noUselessElse
generated program (9 lines) and the fix's diff
--- orig.js 2026-10-17 15:42:28.435412284 -0400 +++ fixed.js 2026-10-17 15:42:28.696406842 -0400 @@ -1,9 +1,8 @@ function f() { let x = 1; if (true) { return x; } - else { + let x = 2; console.log(x); - } } f();
rule documentation given to the models
Summary
- Name: noUselessElse
- Fix: safe
- Default severity: info
- Available from version: 1.3.0
- Diagnostic category: lint/style/noUselessElse
Description
Disallow `else` block when the `if` block breaks early.
If an `if` block breaks early using a breaking statement (`return`, `break`, `continue`, or `throw`),
then the `else` block becomes useless.
Its contents can be placed outside of the block.
If an `if` block breaks early using a breaking statement (`return`, `break`, `continue`, or `throw`),
then the `else` block becomes unnecessary.
This is because the content of the `else` block will never be executed in conjunction with the `if` block,
as the breaking statement ensures the control flow exits the `if` block immediately.
Therefore, the `else` block is redundant, and its content can be placed outside of the block,
reducing the indentation level by one.
Examples
Invalid
```js,expect_diagnostic
while (x > 0) {
if (f(x)) {
break;
} else {
x++
}
}
```
```js,expect_diagnostic
function f(x) {
if (x < 0) {
return 0;
} else {
return x;
}
}
```
```js,expect_diagnostic
function f(x) {
if (x < 0) {
throw new RangeError();
} else {
return x;
}
}
```
Valid
```js
function f(x) {
if (x < 0) {
return 0;
}
return x;
}
```
```js
function f(x) {
if (x < 0) {
console.info("negative number");
} else if (x > 0) {
return x;
} else {
console.info("number 0");
}
}
```