biome style/noUselessElse
labelled safe
Analysis Nemotron 3 Super
The rule flags else blocks following an if statement whose body contains a breaking statement (return, break, continue, throw), marking them as unnecessary.
Fix: Remove the else block and promote its statements to the same indentation level as the if statement, preserving their original order.
12 hazards
- Moving a var declaration from the else block to the outer scope changes its scoping from block-scoped to function-scoped, potentially causing hoisting issues or name collisions.
- If the else block contains a labeled break/continue targeting an outer label, promoting it may alter which loop or switch the label refers to due to changed nesting depth.
- Promoting a throw statement from the else block may change exception handling if the if statement was inside a try block whose catch clause no longer captures the thrown value due to altered control flow.
- If the else block contains a function declaration, moving it to the outer scope may cause early hoisting and unintended availability before the if statement executes.
- When the else block holds a const/let variable that shadows an outer variable, promoting it may cause a syntax error due to duplicate declaration in the same block scope.
- Comments attached to the else block (e.g., // comment else { ... }) may be lost during the rewrite if the tool does not preserve leading or trailing comments on the removed block.
- If the if statement is part of a larger conditional chain (e.g., else if), removing the else may incorrectly merge logic or alter the intended branching structure.
- Promoting statements from the else block may change evaluation order relative to side effects in the if condition or preceding expressions if those expressions rely on timing.
- In strict mode, promoting a with statement from the else block is invalid and will cause a SyntaxError since with is not allowed in strict mode at any scope.
- If the else block contains a debugger statement, moving it may alter debugging behavior if tooling associates breakpoints with specific syntactic contexts.
- When the else block is empty, the fix removes it entirely, but if it contained only a comment, that comment may be dropped even though it had semantic intent (e.g., TODO or license notice).
- If the if condition has a side effect (e.g., function call) and the else block contains a break, promoting the break may cause it to exit a different loop than intended due to altered nesting.
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | invalid | Numeric/String Coercion with + vs Template Literal | Promoting else block changes coercion behavior due to interaction between + operator and template literals when evaluating expressions like `+[]` vs `${}`. |
| r1-p002 | invalid | Evaluation Order Change Due to Side Effects in Condition | Promoting else block moves its statements before the if condition's side effects, altering execution order when condition has observable side effects. |
| r1-p003 | invalid | Order of Evaluation with Side Effects in Expressions | Promoting else block causes expressions in it to be evaluated before the if condition, changing order of side effects when both contain mutations. |
| r1-p004 | fix ok | Break Promoted to Wrong Loop Nesting Level | Promoting a break from else block changes which loop it exits due to altered nesting after fix, causing unintended loop termination. |
| r1-p005 | invalid | ASI Hazard: Leading Parenthesis After Promoted Else Block | After removing else block, promoted statements may begin with '(' causing ASI to incorrectly attach it to prior expression, changing meaning. |
| r1-p006 | invalid | Comment Dropped from Empty Else Block | When else block contains only a comment (e.g., TODO), the fix removes the entire block, dropping the comment despite its semantic intent. |
Sources
r1-p001 · Numeric/String Coercion with + vs Template Literal (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T17-25-0)
1let x = [];
2if (x == 0) { return; } else {
3 console.log(+x + `${x}`);
4}
5console.log('end');
r1-p002 · Evaluation Order Change Due to Side Effects in Condition (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T17-25-0)
1let log = [];
2function f() { log.push('cond'); return true; }
3if (f()) { return; } else {
4 log.push('else');
5}
6console.log(log.join(','));
r1-p003 · Order of Evaluation with Side Effects in Expressions (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T17-25-0)
1let a = 0, b = 0;
2if (++a) { return; } else {
3 b = ++a;
4 console.log(a + ',' + b);
5}
6console.log('done');
r1-p004 · Break Promoted to Wrong Loop Nesting Level
1outer: for (let i = 0; i < 2; i++) {
2 for (let j = 0; j < 2; j++) {
3 if (i === 1) { break outer; } else {
4 break; // inner break
5 }
6 }
7}
8console.log('escaped');
--- orig.js 2026-10-22 13:25:14.561793583 -0400 +++ fixed.js 2026-10-22 13:25:16.525825997 -0400 @@ -1,8 +1,7 @@ outer: for (let i = 0; i < 2; i++) { for (let j = 0; j < 2; j++) { - if (i === 1) { break outer; } else { + if (i === 1) { break outer; } break; // inner break - } } } console.log('escaped');
escaped
r1-p005 · ASI Hazard: Leading Parenthesis After Promoted Else Block (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T17-25-0)
1let y = 1
2if (y) { return; } else {
3 (function(){ y = 2; })()
4}
5console.log(y)
r1-p006 · Comment Dropped from Empty Else Block (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T17-25-0)
1// License: MIT
2if (false) { return; } else {
3 // TODO: handle true case
4}
5console.log('executed')