fixhunt

biome style/useNumberNamespace: fix changes program behavior

fix-changes-behaviorlabelled safereal · mediumrelated
Findings / 2026-10-17T21-04-15-156Z-qk6e-biome-style_useNumberNamespace / r2-p004biome 2.5.154 → 4 lines2026-10-17 21:04 UTC

Hypothesis Nemotron 3 Super predicted to fire fired 1×

var hoisting and re-declaration inside loops or after use

Program

before
1for (var i = 0; i < 2; i++) {
2 var Number = i;
3 console.log(typeof parseInt('1'));
4}
after
1for (var i = 0; i < 2; i++) {
2 var Number = i;
3 console.log(typeof Number.parseInt('1'));
4}

Output

stdout beforeexit 0
number
number
stdout afterexit 1
(no stdout)
TypeError: Number.parseInt is not a function
fired
1 before · 0 after
runs
each version twice, same file name, no network

Judge Nemotron 3 Ultra advisory real · medium

The rule rewrites `parseInt` to `Number.parseInt` assuming `Number` refers to the global namespace, but the program declares a local variable `Number` that shadows it. After the fix, `Number.parseInt` attempts to access a property on the loop variable (a number), causing a TypeError. The documentation does not mention this shadowing scenario, so the fix is not safe for this construct.

Explanation Nemotron 3 Super unverified

The variable declaration `var Number = i;` creates a local binding that shadows the global constructor `Number`. Inside the loop body, any reference to `Number` resolves to this local variable holding numeric values (`0` then `1`). Replacing `parseInt` with `Number.parseInt` attempts to access a method on those numbers, which do not possess such a property, causing a runtime type error whereas the original code correctly invoked the global `parseInt` function each iteration. This change alters observable behavior by introducing an exception where none existed before.

Reproduce

file
prog.js (the before program)
minimized program
r2-p004.js
evidence sheet
r2-p004.md
regression fixture
r2-p004.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/useNumberNamespace --write prog.js
node prog.js

Upstream search GitHub issues Tavily Nemotron 3 Super + Ultra

useNumberNamespace fix · style/useNumberNamespace global variable shadowing · parseInt call reassignment to local Number · typeof check of built-in function after override

  • related biomejs/biome/issues/1228 same rule (useNumberNamespace) but tracking implementation, not this specific broken fix on shadowed Number
  • related biomejs/biome/issues/3578 same rule (useNumberNamespace) but different construct (Infinity property vs parseInt method)
  • related biomejs/biome/issues/2075 same rule (useNumberNamespace) but different construct (isNaN function vs parseInt method)

Details

program
Var hoisting and redeclaration in loop
hazard
var hoisting and re-declaration inside loops or after use
oracle
stdout before: number number stdout after: exit 0 → 1 stderr before: (none) stderr after: TypeError: Number.parseInt is not a function
run
2026-10-17T21-04-15-156Z-qk6e-biome-style_useNumberNamespace
generated program (4 lines) and the fix's diff
1for (var i = 0; i < 2; i++) {
2 var Number = i;
3 console.log(typeof parseInt('1'));
4}
--- orig.js	2026-10-17 17:04:34.895733507 -0400
+++ fixed.js	2026-10-17 17:04:35.164736549 -0400
@@ -1,4 +1,4 @@
 for (var i = 0; i < 2; i++) {
   var Number = i;
-  console.log(typeof parseInt('1'));
+  console.log(typeof Number.parseInt('1'));
 }
rule documentation given to the models
Summary

- Name: useNumberNamespace
- Fix: safe
- Default severity: info
- Available from version: 1.5.0
- Diagnostic category: lint/style/useNumberNamespace


Description

 Use the `Number` properties instead of global ones.

 _ES2015_ moved some globals into the `Number` properties for consistency.

 The rule doesn't report the globals `isFinite` and `isNaN` because they have a slightly different behavior to their corresponding `Number`'s properties `Number.isFinite` and `Number.isNaN`.
 You can use the dedicated rules [noGlobalIsFinite](https://biomejs.dev/linter/rules/no-global-is-finite/) and  [noGlobalIsNan](https://biomejs.dev/linter/rules/no-global-is-nan/) to enforce the use of `Number.isFinite` and `Number.isNaN`.

Examples

Invalid

 ```js,expect_diagnostic
 parseInt("1"); // true
 ```

 ```js,expect_diagnostic
 parseFloat("1.1"); // true
 ```

 ```js,expect_diagnostic
 NaN; // true
 ```

 ```js,expect_diagnostic
 Infinity; // true
 ```

 ```js,expect_diagnostic
 -Infinity; // true
 ```

Valid

 ```js
 Number.parseInt("1"); // false
 ```

 ```js
 Number.parseFloat("1.1"); // false
 ```

 ```js
 Number.NaN; // false
 ```

 ```js
 Number.POSITIVE_INFINITY; // false
 ```

 ```js
 Number.NEGATIVE_INFINITY; // false
 ```