# biome style/noUselessElse: fix changes program behavior

Internal evidence sheet generated by fixhunt. Not an issue text. A human re-verifies, checks the duplicates
below, and writes the upstream report in their own words following the project's AI policy.

- Tool: biome 2.5.15
- Rule: style/noUselessElse (tool labels the fix: safe, this fix reported as safe)
- Oracle: fix-changes-behavior
- Judge (Nemotron 3 Ultra, advisory): real, severity high. The fix hoists a function declaration out of an else block into a switch case clause, where function declarations are not allowed in strict mode and have implementation-dependent semantics in sloppy mode. Before the fix the function was never created (the else was dead code), so typeof g yielded 'undefined'; after the fix the function is created (or a syntax error occurs), changing the observable behavior.
- Program: minimized from 10 to 9 lines

## Reproducer

```js
function main() {
  switch (0) {
    case 0:
      if (false) { return; }
      else { function g() { return 2; } }
      console.log(typeof g);
  }
}
main();
```

## Commands

```sh
node prog.js
bunx @biomejs/biome lint --only=style/noUselessElse --write prog.js
node prog.js
```

## Observed

```
stdout before:
undefined
stdout after:
function
```

## Diff applied by the fix

```diff
--- orig.js	2026-10-22 13:25:25.283970587 -0400
+++ fixed.js	2026-10-22 13:25:25.422972882 -0400
@@ -2,7 +2,7 @@
   switch (0) {
     case 0:
       if (false) { return; }
-      else { function g() { return 2; } }
+      function g() { return 2; } 
       console.log(typeof g);
   }
 }
```

## Why the rewrite is not equivalent (model draft, verify before use)

The original `else` block defines `g` only when the condition is false—here always executed because `if(false)` never runs—but as a function declaration inside a block, it remains scoped to that block in strict mode, making `g` inaccessible outside. After rewriting, `g` becomes a top-level function declaration within the same block scope but now hoisted to the block’s start, still confined to the block. However, JavaScript treats block-scoped function declarations inconsistently across engines; here, the engine likely hoists `g` to the function scope of `main`, making it accessible for `typeof`. Thus, `typeof g` changes from `undefined` (original, due to block scoping) to `function` (rewritten, due to hoisting to outer scope). This alters observable behavior.

## Upstream search

Queries: "noUselessElse fix", "style noUselessElse conditional block", "else clause containing function declaration", "switch case if-else refactoring"

- duplicate: https://github.com/biomejs/biome/issues/11937
  same rule noUselessElse hoisting a function declaration out of an else block into a switch case, colliding with an outer binding and changing typeof g from undefined to function
- related: https://github.com/biomejs/biome/issues/3770
  same rule noUselessElse but about a useful else with break in a for loop, not a function declaration hoisting in a switch case
- related: https://github.com/biomejs/biome/issues/1191
  same rule noUselessElse but about an else-if chain in object pattern matching, not a function declaration hoisting in a switch case
- related: https://github.com/biomejs/biome/issues/4354
  same rule noUselessElse but about not respecting else-if conditional, not a function declaration hoisting in a switch case

<details><summary>All hits</summary>

- [github, open] 💅 `noUselessElse` safe fix hoists a declaration that collides with an outer binding — https://github.com/biomejs/biome/issues/11937
- [github, open] 💅 `noUnnecessaryConditions`: false positive on an overloaded call with `undefined` as the default argument (Vue `inject`) — https://github.com/biomejs/biome/issues/12040
- [github, open] 💅 `noSkippedTests` conditionally skip fix suggestion — https://github.com/biomejs/biome/issues/9295
- [github, open] Extension chokes on large files — https://github.com/biomejs/biome/issues/3860
- [github, open] 💅 `lint/correctness/noUnusedImports` does not consider uses inside comments that precede non-declaration statements (start/end of file, etc.) — https://github.com/biomejs/biome/issues/8762
- [github, open] 💅 `useSortedClasses` cannot sort TailwindCSS classname corretly — https://github.com/biomejs/biome/issues/6498
- [github, closed] 💅 `useSimplifiedLogicExpression` "safe" fix breaks code — https://github.com/biomejs/biome/issues/11351
- [github, closed] 💅 `useExplicitLengthCheck` false positive and broken fix — https://github.com/biomejs/biome/issues/11558
- [github, closed] 💅 noUselessTernary double space in quick fix — https://github.com/biomejs/biome/issues/11092
- [github, closed] 💅 Corrupted CLI safe fix for `useConsistentArrowReturn` — https://github.com/biomejs/biome/issues/8347
- [tavily] 💅 noUselessElse reports useful else · Issue #3770 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/3770
- [tavily] 💅 `noUselessElse` recommendation is wrong · Issue #1191 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/1191
- [tavily] 🐛 Biome ignoring config? · Issue #6459 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/6459
- [tavily] 🐛 `--write` applies fixes to all rules ignoring `--only` · Issue #3470 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/3470
- [github, closed] 💅 noUselessElse does not respect else if conditional — https://github.com/biomejs/biome/issues/4354
- [github, closed] 🐛 Parser fails with "Expected a compound selector" due to @media query — https://github.com/biomejs/biome/issues/3091
- [tavily] format duplicates HTML comments on format. · Issue #11430 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/11430
- [tavily] 💅 Linter does not understand svelte block bindings. Destructuring makes it fail to parse. · Issue #9540 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/9540
- [tavily] 📎 Embedded language formatting · Issue #3334 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/3334

</details>
