biome complexity/noUselessUndefinedInitialization
labelled safe
Analysis Nemotron 3 Super
Flags unnecessary initializations of variables to `undefined`, since they receive that value implicitly.
Fix: Removes the `= undefined` initializer from variable declarations while preserving other declarators in the same statement and moving any inline comments to the end of the declaration.
11 hazards
- In a `for` loop initializer like `for (let i = 0, j = undefined; i < n; i++)`, removing `= undefined` may alter the evaluation order if the omitted initializer had side effects (though `undefined` is literal, Biome treats it as removable only when isolated).
- If a variable declaration with `= undefined` is inside a `with` statement, removing the initializer could change scope resolution if the variable name matches a property in the with object.
- In non-strict mode, a variable named `undefined` could be reassigned, but the rule only flags explicit initialization to the literal `undefined`, so the fix remains safe as it doesn't affect the global `undefined` binding.
- When a declaration like `let x = undefined, y = foo();` is split across lines with a comment after `undefined`, the fix moves the comment to the end of the line, potentially changing its visual association though not its syntactic validity.
- In a `try` block, if `let x = undefined;` is followed by a `return` statement, removing the initializer does not affect control flow since the assignment of `undefined` is a no-op.
- In a comma-separated declaration like `var a = undefined, b = 1;`, removing `= undefined` results in `var a, b = 1;`, which is valid and equivalent because `a` is still implicitly `undefined`.
- If the code relies on the temporal dead zone (TDZ) behavior of `let` or `const`, removing an explicit `= undefined` does not change TDZ semantics since the variable is still not accessed before declaration.
- In a function parameter default like `function f(x = undefined)`, the rule does not trigger, so no fix is applied; thus, no hazard arises from confusing parameter defaults with variable initializers.
- In a class field like `class C { f = undefined; }`, the rule does not trigger (as per valid examples), so no fix is attempted, avoiding incorrect removal of meaningful initializations.
- If a declaration contains a trailing comma after the initializer (e.g., `let x = undefined,`), removing `= undefined` may leave a dangling comma, but Biome's formatter handles this by adjusting the syntax appropriately during the fix.
- In a destructuring pattern like `let [a = undefined] = [];`, the rule does not currently flag this (per documentation focus on simple initializations), so no fix is applied, preventing incorrect simplification of destructuring defaults.
Findings
| program | oracle | label | judge | status | summary |
|---|---|---|---|---|---|
| r1-p005 | fix-changes-behavior | labelled safe | real · high | duplicate | The fix removes the explicit `= undefined` initializer from a `var` declaration inside a loop. Because `var` is function-scoped, the original code re-initializ… |
| r1-p007 | fix-changes-behavior | labelled safe | real · high | duplicate | The fix removes the explicit `= undefined` initializer from a `var` declaration inside a block, but `var` is function-scoped and hoisted. The original code re-… |
| r2-p002 | fix-changes-behavior | labelled safe | real · high | related | The rule assumes the global `undefined` binding, but the program shadows `undefined` with a local variable holding 42. The fix removes the initializer, changin… |
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | silent prediction off | Sparse Arrays - Hole Creation | sparse arrays, holes, Array(n) vs [n], array-likes |
| r1-p002 | fix ok | Comment Movement Preservation | comments attached to the removed or moved code |
| r1-p003 | fix ok | Coercion Differences in Template Literals | numeric/string coercion: + vs template literal, objects with toString/valueOf, Symbol, BigInt |
| r1-p004 | silent | Exception During Initialization Evaluation | exceptions thrown inside the code the fix removes or rewrites |
| r1-p005 | fix-changes-behavior | Var Hoisting and Redeclaration in Loop | var hoisting and re-declaration inside loops or after use |
| r1-p006 | fix ok | For Loop Initializer Comma Sequence | In a `for` loop initializer like `for (let i = 0, j = undefined; i < n; i++)`, removing `= undefined` may alter the evaluation order if the omitted initializer had side effects |
| r1-p007 | fix-changes-behavior | Comma-Separated Declaration Equivalence | In a comma-separated declaration like `var a = undefined, b = 1;`, removing `= undefined` results in `var a, b = 1;`, which is valid and equivalent because `a` is still implicitly `undefined`. |
| r1-p008 | invalid | Nullish Coalescing and Optional Chaining Sensitivity | null/undefined distinction, optional chaining short-circuit, nullish vs falsy |
| r2-p001 | fix ok | Temporal Dead Zone After Hoisting | temporal dead zone after code is hoisted or reordered |
| r2-p002 | fix-changes-behavior | Non-Strict Mode Undefined Reassignment Safety | In non-strict mode, a variable named `undefined` could be reassigned, but the rule only flags explicit initialization to the literal `undefined`, so the fix remains safe as it doesn't affect the globa |
| r2-p003 | silent | Destructuring Default Not Flagged | In a destructuring pattern like `let [a = undefined] = [];`, the rule does not currently flag this (per documentation focus on simple initializations), so no fix is applied, preventing incorrect simpl |
| r2-p004 | fix ok | Coercion Differences: + vs Template Literal | numeric/string coercion: + vs template literal, objects with toString/valueOf, Symbol, BigInt |
| r2-p005 | fix ok | Function Declarations Inside Blocks | function declarations inside blocks, switch cases, labeled statements |
| r2-p006 | silent prediction off | Exception During Fix Removal | exceptions thrown inside the code the fix removes or rewrites |
| r2-p007 | fix ok | This Binding in Arrow vs Function | this binding: arrow vs function, methods extracted from objects, call/apply/bind |
| r2-p008 | silent prediction off | Getter/Setter and DefineProperty Side Effects | getters, setters and Object.defineProperty side effects |
Sources
r1-p001 · Sparse Arrays - Hole Creation
1function test(arr) {
2 return arr.length === 3 && Number.isNaN(arr[1]);
3}
4
5// Create sparse array via direct assignment to index 2
6let a = [];
7a[2] = 1; // Creates hole at index 0,1 -> [empty × 2, 1]
8console.log('Direct:', test(a));
9
10// Recreate using pattern rule flags: explicit undefined then assignment
11let b = [];
12b[0] = undefined; // Rule triggers here
13b[2] = 1;
14console.log('After undefined assign:', test(b)); // Should differ due to hole vs undefined
Direct: false After undefined assign: false
r1-p002 · Comment Movement Preservation
1function getValue(flag) {
2 // Flag-controlled initialization
3 let x = undefined; /* important note */
4 if (flag) x = 42;
5 return x;
6}
7
8console.log('Flag false:', getValue(false));
9console.log('Flag true:', getValue(true));
--- orig.js 2026-10-17 16:10:27.988408380 -0400 +++ fixed.js 2026-10-17 16:10:28.246400801 -0400 @@ -1,6 +1,6 @@ function getValue(flag) { // Flag-controlled initialization - let x = undefined; /* important note */ + let x ; /* important note */ if (flag) x = 42; return x; }
Flag false: undefined Flag true: 42
r1-p003 · Coercion Differences in Template Literals
1const obj = {
2 toString() { return 'obj'; },
3 valueOf() { return 42; }
4};
5
6let u = undefined; // Rule triggers
7console.log('+ coercion:', String(u + obj));
8console.log('template literal:', `${u}${obj}`);
9
10// Change u via reassignment
11test();
12function test() { u = 'changed'; }
13console.log('After reassignment +:', String(u + obj));
14console.log('After reassignment template:', `${u}${obj}`);
--- orig.js 2026-10-17 16:10:28.413395896 -0400 +++ fixed.js 2026-10-17 16:10:28.682387995 -0400 @@ -3,7 +3,7 @@ valueOf() { return 42; } }; -let u = undefined; // Rule triggers +let u ; // Rule triggers console.log('+ coercion:', String(u + obj)); console.log('template literal:', `${u}${obj}`);
+ coercion: NaN template literal: undefinedobj After reassignment +: changed42 After reassignment template: changedobj
r1-p004 · Exception During Initialization Evaluation
1let throws = false;
2function sideEffect() {
3 if (throws) throw new Error('side effect');
4 return 'ok';
5}
6
7try {
8 let x = sideEffect(); // Not undefined init → rule silent
9 console.log('Assigned:', x);
10} catch (e) {
11 console.log('Caught:', e.name, e.message);
12}
13
14throws = true;
15try {
16 let y = sideEffect();
17 console.log('Assigned:', y);
18} catch (e) {
19 console.log('Caught:', e.name, e.message);
20}
Assigned: ok Caught: Error side effect
r1-p005 · Var Hoisting and Redeclaration in Loop
1function scopeTest() {
2 console.log('a before loop:', typeof a); // hoisted, undefined
3 for (let i = 0; i < 2; i++) {
4 var a = undefined; // Rule triggers twice
5 console.log('Iteration', i, 'a =', a);
6 a = i * 10;
7 }
8 console.log('a after loop:', a); // Should be 10 from last iteration
9}
10
11scopeTest();
--- orig.js 2026-10-17 16:10:29.082376252 -0400 +++ fixed.js 2026-10-17 16:10:29.366367928 -0400 @@ -1,7 +1,7 @@ function scopeTest() { console.log('a before loop:', typeof a); // hoisted, undefined for (let i = 0; i < 2; i++) { - var a = undefined; // Rule triggers twice + var a ; // Rule triggers twice console.log('Iteration', i, 'a =', a); a = i * 10; }
a before loop: undefined Iteration 0 a = undefined Iteration 1 a = undefined a after loop: 10
r1-p006 · For Loop Initializer Comma Sequence
1let log = '';
2function mark() { log += 'called'; return undefined; }
3
4for (let i = 0, j = mark(); i < 2; i++) { // Rule does NOT trigger (not isolated undefined)
5 log += `-i${i}-j${j}`;
6}
7console.log('Log (should show call):', log);
8
9// Separate test: isolated undefined in comma decl
10log = '';
11for (let i = 0; i < 1; i++) {
12 let a = undefined, b = 1; // Rule triggers on a
13 log += `a${a}b${b}`;
14}
15console.log('After fix equivalent:', log);
--- orig.js 2026-10-17 16:10:29.527363210 -0400 +++ fixed.js 2026-10-17 16:10:29.787355590 -0400 @@ -9,7 +9,7 @@ // Separate test: isolated undefined in comma decl log = ''; for (let i = 0; i < 1; i++) { - let a = undefined, b = 1; // Rule triggers on a + let a , b = 1; // Rule triggers on a log += `a${a}b${b}`; } console.log('After fix equivalent:', log);
Log (should show call): called-i0-jundefined-i1-jundefined After fix equivalent: aundefinedb1
r1-p007 · Comma-Separated Declaration Equivalence
1function commaTest() {
2 var a = undefined, b = 1; // Rule triggers on a
3 console.log('Initial:', typeof a, b);
4 a = 'assigned';
5 console.log('After reassignment:', a, b);
6
7 // Re-enter scope to test re-declaration
8 if (true) {
9 var a = undefined, c = 2; // Rule triggers again
10 console.log('Redecled:', a, c);
11 }
12 console.log('After redeclaration:', a, typeof c);
13}
14
15commaTest();
--- orig.js 2026-10-17 16:10:29.950350814 -0400 +++ fixed.js 2026-10-17 16:10:30.215343061 -0400 @@ -1,12 +1,12 @@ function commaTest() { - var a = undefined, b = 1; // Rule triggers on a + var a , b = 1; // Rule triggers on a console.log('Initial:', typeof a, b); a = 'assigned'; console.log('After reassignment:', a, b); // Re-enter scope to test re-declaration if (true) { - var a = undefined, c = 2; // Rule triggers again + var a , c = 2; // Rule triggers again console.log('Redecled:', a, c); } console.log('After redeclaration:', a, typeof c);
Initial: undefined 1 After reassignment: assigned 1 Redecled: undefined 2 After redeclaration: undefined number
r1-p008 · Nullish Coalescing and Optional Chaining Sensitivity (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-17T20-10-1)
1function process(input) {
2 let data = undefined; // Rule triggers
3 console.log('data == null:', data == null);
4 console.log('data === null:', data === null);
5 console.log('data ?? "default":', data ?? 'default');
6 console.log('data || "fallback":', data || 'fallback');
7
8 const obj = { value: 42 };
9 console.log('obj.prop?.length:', obj.prop?.length);
10 console.log('obj[data]?.prop:', obj[data]?.prop);
11}
12
13process();
14
15// Show difference if data were null
16data = null;
17console.log('\nWith null:');
18console.log('data == null:', data == null);
19console.log('data === null:', data === null);
20console.log('data ?? "default":', data ?? 'default');
21console.log('data || "fallback":', data || 'fallback');
22}
r2-p001 · Temporal Dead Zone After Hoisting
1function test() {
2 console.log(typeof x); // Should log 'undefined' before init
3 var x = undefined;
4 console.log(x);
5}
6test();
--- orig.js 2026-10-17 16:10:34.450219722 -0400 +++ fixed.js 2026-10-17 16:10:34.726211722 -0400 @@ -1,6 +1,6 @@ function test() { console.log(typeof x); // Should log 'undefined' before init - var x = undefined; + var x ; console.log(x); } test();
undefined undefined
r2-p002 · Non-Strict Mode Undefined Reassignment Safety
1(function() {
2 'use sloppy';
3 var undefined = 42;
4 var x = undefined;
5 console.log(x);
6})();
--- orig.js 2026-10-17 16:10:34.886207085 -0400 +++ fixed.js 2026-10-17 16:10:35.161199124 -0400 @@ -1,6 +1,6 @@ (function() { 'use sloppy'; var undefined = 42; - var x = undefined; + var x ; console.log(x); })();
42
r2-p003 · Destructuring Default Not Flagged
1let [a = undefined] = [];
2console.log(a);
undefined
r2-p004 · Coercion Differences: + vs Template Literal
1let x = undefined;
2const obj = { toString() { return '42'; }, valueOf() { return 0; } };
3console.log(String(x) + obj);
4console.log(`${x}${obj}`);
--- orig.js 2026-10-17 16:10:35.556187700 -0400 +++ fixed.js 2026-10-17 16:10:35.815180210 -0400 @@ -1,4 +1,4 @@ -let x = undefined; +let x ; const obj = { toString() { return '42'; }, valueOf() { return 0; } }; console.log(String(x) + obj); console.log(`${x}${obj}`);
undefined0 undefined42
r2-p005 · Function Declarations Inside Blocks
1if (true) {
2 function inner() {
3 var tmp = undefined;
4 return tmp;
5 }
6 console.log(inner());
7}
--- orig.js 2026-10-17 16:10:35.987175235 -0400 +++ fixed.js 2026-10-17 16:10:36.260167357 -0400 @@ -1,6 +1,6 @@ if (true) { function inner() { - var tmp = undefined; + var tmp ; return tmp; } console.log(inner());
undefined
r2-p006 · Exception During Fix Removal
1let y;
2try {
3 y = undefined;
4 throw new Error('test');
5} catch (e) {
6 console.log(y === undefined, e.message);
7}
true test
r2-p007 · This Binding in Arrow vs Function
1const obj = {
2 val: 42,
3 regular: function() {
4 var x = undefined;
5 return () => {
6 console.log(this.val, x);
7 };
8 }
9};
10const fn = obj.regular();
11fn();
--- orig.js 2026-10-17 16:10:36.647156189 -0400 +++ fixed.js 2026-10-17 16:10:36.922148253 -0400 @@ -1,7 +1,7 @@ const obj = { val: 42, regular: function() { - var x = undefined; + var x ; return () => { console.log(this.val, x); };
42 undefined
r2-p008 · Getter/Setter and DefineProperty Side Effects
1const obj = {};
2Object.defineProperty(obj, 'prop', {
3 get() { return this._val; },
4 set(v) { this._val = v; }
5});
6obj.prop = undefined;
7console.log(obj.prop);
undefined