fixhunt

biome style/useConst

labelled safe
Runs / 2026-10-17T21-01-06-042Z-shrf-biome-style_useConstbiome 2.5.152026-10-17 21:01 UTC8 programs × 2 round(s)16 programs, 10 fired, 9 fixed, 0 findings, 2 rejectedmodel cost $0.0033

Analysis Nemotron 3 Super

Flags `let` declarations where the variable is never reassigned after initialization.

Fix: Replaces `let` with `const` for each variable declarator that has an initializer or is assigned exactly once before any reassignment, preserving declarators, commas, and block structure while removing the `let` keyword and inserting `const`.

12 hazards
  • Rewriting `let` in a loop header like `for (let i of arr)` to `const` causes a TypeError because `const` bindings cannot be reassigned per iteration.
  • Changing `let` to `const` in a block-scoped redeclaration such as `{ let a = 1; let a = 2; }` results in a SyntaxError due to duplicate `const` declarations in the same block.
  • If the initializer contains a `delete` expression targeting an unqualified identifier (e.g., `let x = delete y;`), converting to `const` may throw a SyntaxError in strict mode because `const` bindings cannot be deleted.
  • When the variable is conditionally declared (e.g., `if (x) let y = 1;`), replacing `let` with `const` can cause a ReferenceError if the block is not entered, as `const` is not hoisted and remains inaccessible outside its block.
  • In non-strict mode, if the initializer assigns to an undeclared variable (e.g., `let a = (b = 5);`), switching to `const` may silently create a global variable instead of throwing, altering implicit globals behavior.
  • If the declarator lacks an initializer and is assigned later (e.g., `let a; a = 1;`), the fix incorrectly applies `const` to the uninitialized declarator, causing a SyntaxError because `const` must be initialized at declaration.
  • Moving a `let` declaration to `const` across a function boundary (e.g., from outer to inner scope via hoisting misunderstandings) breaks encapsulation and may expose unintended variables.
  • Comments attached to the `let` keyword or declarators (e.g., `let /* ignored */ x = 1;`) may be stripped or misplaced during the rewrite, altering source formatting or tooling expectations.
  • In a `try` block (e.g., `try { let e = 5; }`), rewriting to `const` is safe only if no reassignment occurs, but if the variable is referenced in `finally` after potential reassignment in `catch`, the timing of binding initialization may differ.
  • When used with `export let` (non-standard but possible in some environments), replacing with `export const` may break bindings expected to be mutable by importers.
  • If the variable name is `let` or `const` itself (e.g., `let let = 5;`), the rewrite produces invalid syntax (`const const = 5;`).
  • In eval contexts or dynamic scope manipulations, changing `let` to `const` alters the mutability of the binding, which may be relied upon for runtime redefinition via indirect eval.

Programs

idresulttitlehazard
r1-p001fix okASI and semicolon-less code with leading parenthesisWhen `let` is converted to `const` in ASI-prone code without semicolons, a following line starting with `(` or `[` can be misinterpreted as a function call or array indexing on the prior expression, c
r1-p002silent prediction offMoving let to const across function boundary breaks encapsulationIf a `let` declared in an outer scope is reassigned inside an inner function, converting it to `const` prevents reassignment and alters behavior. This tests whether the linter incorrectly hoists or mi
r1-p003fix okNon-strict mode: initializer assigns to undeclared variableIn sloppy mode, `let a = (b = 5);` creates a global `b`. If `let` becomes `const`, the assignment still happens but `b` remains global—however, if the linter mistakenly treats the inner assignment as
r1-p004fix okStrict vs sloppy mode semanticsIn strict mode, assigning to an undeclared variable throws; in sloppy mode it creates a global. Converting `let` to `const` doesn't change this directly, but if the initializer has such an assignment,
r1-p005fix okSparse arrays, holes, Array(n) vs [n]When initializing a `let` variable with an array literal containing holes (e.g., `[, , 3]`), converting to `const` should preserve the array structure. However, if the linter mishandles the initialize
r1-p006fix okRegular expressions: escapes, unicode flag, lastIndex with g flagIf a `let` variable holds a regex with `/g` flag, its `lastIndex` mutates on each `exec`. Converting `let` to `const` should not affect this mutability. But if the linter incorrectly assumes immutabil
r1-p007invalidBlock-scoped redeclaration with const causes SyntaxErrorTwo `let` declarations in the same block are allowed; converting both to `const` causes a `SyntaxError` due to duplicate `const` declarations. This tests whether the linter attempts to rewrite both wi
r1-p008silent prediction offOrder of evaluation when expressions are merged or duplicatedIf a `let` variable's initializer has side effects (e.g., function calls), and the linter duplicates or merges expressions during rewrite, those effects might run twice or not at all. We use a comma-s
r2-p001fired, no fixUnassigned let converted to constIf the declarator lacks an initializer and is assigned later (e.g., `let a; a = 1;`), the fix incorrectly applies `const` to the uninitialized declarator, causing a SyntaxError because `const` must be
r2-p002invalidDelete unqualified identifier in initializerIf the initializer contains a `delete` expression targeting an unqualified identifier (e.g., `let x = delete y;`), converting to `const` may throw a SyntaxError in strict mode because `const` bindings
r2-p003fix ok prediction offConditional let declarationWhen the variable is conditionally declared (e.g., `if (x) let y = 1;`), replacing `let` with `const` can cause a ReferenceError if the block is not entered, as `const` is not hoisted and remains inac
r2-p004fix okNumeric/string coercion with toString/valueOfnumeric/string coercion: + vs template literal, objects with toString/valueOf, Symbol, BigInt
r2-p005silent prediction offExport let (non-standard)When used with `export let` (non-standard but possible in some environments), replacing with `export const` may break bindings expected to be mutable by importers.
r2-p006fix ok__proto__ and prototype access__proto__ keys, prototype access, Object.assign vs spread
r2-p007silent prediction offStrict vs sloppy mode semanticsstrict vs sloppy mode semantics
r2-p008fix okEval context mutabilityIn eval contexts or dynamic scope manipulations, changing `let` to `const` alters the mutability of the binding, which may be relied upon for runtime redefinition via indirect eval.

Sources

r1-p001 · ASI and semicolon-less code with leading parenthesis
1let x = 5
2[1,2].forEach(v=>console.log(x+v))
--- orig.js	2026-10-17 17:01:20.097451115 -0400
+++ fixed.js	2026-10-17 17:01:20.379454550 -0400
@@ -1,2 +1,2 @@
-let x = 5
+const x = 5
 [1,2].forEach(v=>console.log(x+v))
r1-p002 · Moving let to const across function boundary breaks encapsulation
1let v = 0;
2function update() { v = 42; }
3update();
4console.log(v);
42
r1-p003 · Non-strict mode: initializer assigns to undeclared variable
1(function(){ 'use sloppy'; let a = (b = 5); console.log(typeof b, b); })();
--- orig.js	2026-10-17 17:01:20.778459409 -0400
+++ fixed.js	2026-10-17 17:01:21.052462746 -0400
@@ -1 +1 @@
-(function(){ 'use sloppy'; let a = (b = 5); console.log(typeof b, b); })();
+(function(){ 'use sloppy'; const a = (b = 5); console.log(typeof b, b); })();
r1-p004 · Strict vs sloppy mode semantics
1'use strict';
2try {
3 let c = (d = 1);
4} catch(e) {
5 console.log(e.name, e.message);
6}
--- orig.js	2026-10-17 17:01:21.225464852 -0400
+++ fixed.js	2026-10-17 17:01:21.502468224 -0400
@@ -1,6 +1,6 @@
 'use strict';
 try {
-  let c = (d = 1);
+  const c = (d = 1);
 } catch(e) {
   console.log(e.name, e.message);
 }
ReferenceError d is not defined
r1-p005 · Sparse arrays, holes, Array(n) vs [n]
1let arr = [, , 3];
2console.log(arr.length, arr[0], arr[1], arr[2]);
--- orig.js	2026-10-17 17:01:21.677470354 -0400
+++ fixed.js	2026-10-17 17:01:21.965473860 -0400
@@ -1,2 +1,2 @@
-let arr = [, , 3];
+const arr = [, , 3];
 console.log(arr.length, arr[0], arr[1], arr[2]);
3 undefined undefined 3
r1-p006 · Regular expressions: escapes, unicode flag, lastIndex with g flag
1let re = /a/g;
2console.log(re.exec('aba'), re.lastIndex);
3console.log(re.exec('aba'), re.lastIndex);
--- orig.js	2026-10-17 17:01:22.140475990 -0400
+++ fixed.js	2026-10-17 17:01:22.413479312 -0400
@@ -1,3 +1,3 @@
-let re = /a/g;
+const re = /a/g;
 console.log(re.exec('aba'), re.lastIndex);
 console.log(re.exec('aba'), re.lastIndex);
[ 'a', index: 0, input: 'aba', groups: undefined ] 1
[ 'a', index: 2, input: 'aba', groups: undefined ] 3
r1-p007 · Block-scoped redeclaration with const causes SyntaxError (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-17T21-01-0)
1{ let a = 1; let a = 2; console.log(a); }
r1-p008 · Order of evaluation when expressions are merged or duplicated
1let n = 0, x = (n++, 10);
2console.log(n, x);
1 10
r2-p001 · Unassigned let converted to const
1let a;
2a = 1;
3console.log(a);
1
r2-p002 · Delete unqualified identifier in initializer (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-17T21-01-0)
1"use strict";
2let x = delete y;
3console.log(x);
r2-p003 · Conditional let declaration
1if (false) { let y = 1; }
2try { console.log(y); } catch (e) { console.log(e.name + ': ' + e.message); }
--- orig.js	2026-10-17 17:01:27.815544970 -0400
+++ fixed.js	2026-10-17 17:01:28.092548333 -0400
@@ -1,2 +1,2 @@
-if (false) { let y = 1; }
+if (false) { const y = 1; }
 try { console.log(y); } catch (e) { console.log(e.name + ': ' + e.message); }
ReferenceError: y is not defined
r2-p004 · Numeric/string coercion with toString/valueOf
1let o = { valueOf: () => 2, toString: () => '3' };
2let result = o + '';
3console.log(result);
--- orig.js	2026-10-17 17:01:28.269550481 -0400
+++ fixed.js	2026-10-17 17:01:28.535553709 -0400
@@ -1,3 +1,3 @@
-let o = { valueOf: () => 2, toString: () => '3' };
-let result = o + '';
+const o = { valueOf: () => 2, toString: () => '3' };
+const result = o + '';
 console.log(result);
2
r2-p005 · Export let (non-standard)
1export let counter = 0;
2counter++;
3console.log(counter);
1
r2-p006 · __proto__ and prototype access
1let obj = { __proto__: { x: 1 } };
2console.log(obj.x);
--- orig.js	2026-10-17 17:01:28.940558624 -0400
+++ fixed.js	2026-10-17 17:01:29.224562070 -0400
@@ -1,2 +1,2 @@
-let obj = { __proto__: { x: 1 } };
+const obj = { __proto__: { x: 1 } };
 console.log(obj.x);
1
r2-p007 · Strict vs sloppy mode semantics
1"use strict";
2try { let v = 1; v = 2; } catch (e) { console.log(e.name); }
3(function() { "use sloppy"; let w = 1; w = 2; console.log(w); })();
2
r2-p008 · Eval context mutability
1let global = (0, eval)('this');
2let x = 1;
3(0, eval)('x = 2');
4console.log(x);
--- orig.js	2026-10-17 17:01:29.623566910 -0400
+++ fixed.js	2026-10-17 17:01:29.893570185 -0400
@@ -1,4 +1,4 @@
-let global = (0, eval)('this');
-let x = 1;
+const global = (0, eval)('this');
+const x = 1;
 (0, eval)('x = 2');
 console.log(x);
1