fixhunt

eslint prefer-const

labelled safe
Runs / 2026-10-22T18-25-31-443Z-sq5v-eslint-prefer-consteslint 9.39.52026-10-22 18:25 UTC8 programs × 2 round(s)16 programs, 14 fired, 12 fixed, 0 findings, 1 rejectedmodel cost $0.0033

Analysis Nemotron 3 Super

Flags let-declared variables that are never reassigned after initialization.

Fix: Replaces 'let' with 'const' for variables that are never reassigned after their initial assignment.

10 hazards
  • Rewriting 'let' to 'const' in a block-scoped loop initializer like 'for (let i = 0; i < n; ++i)' breaks reassignment and causes a TypeError.
  • Changing 'let' to 'const' for a variable declared in a conditional block but used outside (e.g., 'if (true) let x = 1;') moves the declaration into the block scope, making it inaccessible outside and causing a ReferenceError.
  • If the variable is read before its assignment (e.g., 'let x; console.log(x); x = 1;'), replacing 'let' with 'const' creates a temporal dead zone, causing a ReferenceError on the read.
  • In destructuring like 'let {a, b} = obj;', rewriting only 'b' to 'const' when 'a' is reassigned later leaves 'b' as const but may mislead if 'b' is actually used in a way that assumes mutability (though rare).
  • If the variable is declared with 'let' in the init part of a for-in or for-of loop (e.g., 'for (let k in obj)'), changing to 'const' is correct per spec (new binding per iteration), but if the loop body relies on reassignment of the variable across iterations (which it shouldn't), it could break—though the rule only fires when there is no reassignment, so this is safe in practice.
  • If the variable is declared in a class static block (e.g., 'static { let x = 1; }'), rewriting to 'const' is safe because the block has its own scope and no reassignment occurs.
  • If the variable is declared in a scope where it is shadowed later (e.g., 'let x = 1; { let x = 2; }'), changing the outer 'let' to 'const' does not affect the inner shadowing and is safe.
  • If the variable is declared but never used (e.g., 'let unused = 1;'), changing to 'const' is safe and may even help tools detect unused variables.
  • If the variable is initialized with a function call that has side effects (e.g., 'let x = foo();'), moving the declaration to const does not change the timing or number of side effects.
  • If the variable is declared in a comma-separated list (e.g., 'let a = 1, b = 2;'), rewriting only 'b' to 'const' when 'a' is reassigned later results in mixed const/let in the same statement, which is syntactically valid but may confuse readers or tools expecting uniformity.

Programs

idresulttitlehazard
r1-p001fix okEvaluation Order - Side Effect Duplicationorder of evaluation when expressions are merged, duplicated or deleted (side effects run twice or never)
r1-p002fix okStatic Block Scope SafetyIf the variable is declared in a class static block (e.g., 'static { let x = 1; }'), rewriting to 'const' is safe because the block has its own scope and no reassignment occurs.
r1-p003fix okPartial Destructuring Misleading ConstIn destructuring like 'let {a, b} = obj;', rewriting only 'b' to 'const' when 'a' is reassigned later leaves 'b' as const but may mislead if 'b' is actually used in a way that assumes mutability (thou
r1-p004fix okRegExp lastIndex Shared Mutationregular expressions: escapes, unicode flag, lastIndex with the g flag
r1-p005fix okthis Binding in Extracted Methodthis binding: arrow vs function, methods extracted from objects, call/apply/bind
r1-p006invalidStrict vs Sloppy Mode Semanticsstrict vs sloppy mode semantics
r1-p007fired, no fixMixed const/let in Comma DeclarationIf the variable is declared in a comma-separated list (e.g., 'let a = 1, b = 2;'), rewriting only 'b' to 'const' when 'a' is reassigned later results in mixed const/let in the same statement, which is
r1-p008fix okClass Fields and Private Names Interactionclass fields, static blocks, private names, super calls
r2-p001fix okarguments-object-default-restarguments object, function.length, default parameters, rest parameters
r2-p002fix ok prediction offclass-static-block-safetyvariable declared in a class static block – rewriting to const is safe due to isolated scope
r2-p003fired, no fixtemporal-dead-zone-read-before-assignvariable read before assignment – let → const causes TDZ ReferenceError
r2-p004silent prediction offcomments-attached-to-removed-codecomments attached to the removed or moved code
r2-p005fix okname-collision-shadow-after-movename collisions across scopes after a move (shadowing)
r2-p006fix okasi-semicolonless-leading-paren-bracketASI and semicolon-less code, leading ( or [ on the next line
r2-p007fix okclass-fields-static-blocks-private-names-superclass fields, static blocks, private names, super calls
r2-p008fix okvar-hoisting-redeclaration-inside-loops-after-usevar hoisting and re-declaration inside loops or after use

Sources

r1-p001 · Evaluation Order - Side Effect Duplication
1function get() { return ++counter; }
2let counter = 0;
3console.log(get(), get());
4counter = 0;
5{ let temp = get(); console.log(temp, temp); }
--- orig.js	2026-10-22 14:25:40.987105514 -0400
+++ fixed.js	2026-10-22 14:25:43.661224897 -0400
@@ -2,4 +2,4 @@
 let counter = 0;
 console.log(get(), get());
 counter = 0;
-{ let temp = get(); console.log(temp, temp); }
+{ const temp = get(); console.log(temp, temp); }
1 2
1 1
r1-p002 · Static Block Scope Safety
1class C {
2 static { let x = 1; console.log(x); }
3}
4new C(); // triggers rule on x → becomes const, still logs 1
--- orig.js	2026-10-22 14:25:40.988105559 -0400
+++ fixed.js	2026-10-22 14:25:44.790275316 -0400
@@ -1,4 +1,4 @@
 class C {
-  static { let x = 1; console.log(x); }
+  static { const x = 1; console.log(x); }
 }
 new C(); // triggers rule on x → becomes const, still logs 1
1
r1-p003 · Partial Destructuring Misleading Const
1let obj = {a: 1, b: 2};
2let {a, b} = obj;
3a = 99; // reassigned
4console.log(a, b);
5obj.b = 88; // b not mutated via obj, but user might expect it could be
6console.log(obj.b); // shows 88, but b is const → confusion risk
--- orig.js	2026-10-22 14:25:40.989105603 -0400
+++ fixed.js	2026-10-22 14:25:43.649224361 -0400
@@ -1,4 +1,4 @@
-let obj = {a: 1, b: 2};
+const obj = {a: 1, b: 2};
 let {a, b} = obj;
 a = 99; // reassigned
 console.log(a, b);
99 2
88
r1-p004 · RegExp lastIndex Shared Mutation
1let regex = /a/g;
2let str = 'aa';
3let match;
4while ((match = regex.exec(str)) !== null) {
5 console.log(match.index);
6}
7// After fix: let → const, but regex still mutable via lastIndex
8console.log('done');
--- orig.js	2026-10-22 14:25:40.990105648 -0400
+++ fixed.js	2026-10-22 14:25:43.675225522 -0400
@@ -1,5 +1,5 @@
-let regex = /a/g;
-let str = 'aa';
+const regex = /a/g;
+const str = 'aa';
 let match;
 while ((match = regex.exec(str)) !== null) {
   console.log(match.index);
0
1
done
r1-p005 · this Binding in Extracted Method
1let obj = {
2 value: 42,
3 getValue: function() { return this.value; }
4};
5let fn = obj.getValue;
6console.log(fn()); // undefined (sloppy)
7'use strict';
8let obj2 = {
9 value: 99,
10 getValue: function() { return this.value; }
11};
12let fn2 = obj2.getValue;
13console.log(fn2()); // undefined (strict)
--- orig.js	2026-10-22 14:25:40.990105648 -0400
+++ fixed.js	2026-10-22 14:25:43.646224227 -0400
@@ -1,13 +1,13 @@
-let obj = {
+const obj = {
   value: 42,
   getValue: function() { return this.value; }
 };
-let fn = obj.getValue;
+const fn = obj.getValue;
 console.log(fn()); // undefined (sloppy)
 'use strict';
-let obj2 = {
+const obj2 = {
   value: 99,
   getValue: function() { return this.value; }
 };
-let fn2 = obj2.getValue;
+const fn2 = obj2.getValue;
 console.log(fn2()); // undefined (strict)
undefined
undefined
r1-p006 · Strict vs Sloppy Mode Semantics (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T18-25-3)
1'use strict';
2let x = 1;
3try { delete x; } catch(e) { console.log(e.name); }
4
5// Sloppy mode equivalent
6(function() {
7 let y = 1;
8 try { delete y; } catch(e) { console.log(e.name); }
9})();
r1-p007 · Mixed const/let in Comma Declaration
1let a = 1, b = 2;
2a = 3;
3console.log(a, b);
4// After fix: let a = 1, const b = 2; → a reassigned, b const → valid but mixed
3 2
r1-p008 · Class Fields and Private Names Interaction
1class Base {
2 static { let baseInit = 1; console.log('base:', baseInit); }
3}
4class Derived extends Base {
5 static { let derivedInit = 2; console.log('derived:', derivedInit); }
6 #x = baseInit + derivedInit; // Error: baseInit not accessible
7}
8try { new Derived(); } catch(e) { console.log(e.name); }
--- orig.js	2026-10-22 14:25:44.818276567 -0400
+++ fixed.js	2026-10-22 14:25:47.431393293 -0400
@@ -1,8 +1,8 @@
 class Base {
-  static { let baseInit = 1; console.log('base:', baseInit); }
+  static { const baseInit = 1; console.log('base:', baseInit); }
 }
 class Derived extends Base {
-  static { let derivedInit = 2; console.log('derived:', derivedInit); }
+  static { const derivedInit = 2; console.log('derived:', derivedInit); }
   #x = baseInit + derivedInit; // Error: baseInit not accessible
 }
 try { new Derived(); } catch(e) { console.log(e.name); }
base: 1
derived: 2
ReferenceError
r2-p001 · arguments-object-default-rest
1function f(a = g(), ...rest) {
2 let len = arguments.length;
3 console.log('len:', len, 'a:', a, 'rest:', rest.join(',')||'empty');
4}
5function g() { return 1; }
6f();
--- orig.js	2026-10-22 14:25:52.579623390 -0400
+++ fixed.js	2026-10-22 14:25:56.905816880 -0400
@@ -1,5 +1,5 @@
 function f(a = g(), ...rest) {
-  let len = arguments.length;
+  const len = arguments.length;
   console.log('len:', len, 'a:', a, 'rest:', rest.join(',')||'empty');
 }
 function g() { return 1; }
len: 0 a: 1 rest: empty
r2-p002 · class-static-block-safety
1class C {
2 static {
3 let x = 1;
4 console.log('static init:', x);
5 }
6 constructor() { console.log('instance:', C.x ?? 'undefined'); }
7}
8new C();
--- orig.js	2026-10-22 14:25:52.580623435 -0400
+++ fixed.js	2026-10-22 14:25:56.982820325 -0400
@@ -1,6 +1,6 @@
 class C {
   static {
-    let x = 1;
+    const x = 1;
     console.log('static init:', x);
   }
   constructor() { console.log('instance:', C.x ?? 'undefined'); }
static init: 1
instance: undefined
r2-p003 · temporal-dead-zone-read-before-assign
1let x;
2console.log(typeof x);
3x = 42;
4console.log('x:', x);
undefined
x: 42
r2-p004 · comments-attached-to-removed-code
1let y = 1; // initialized
2console.log('y:', y);
3y = 2;
y: 1
r2-p005 · name-collision-shadow-after-move
1{ let tmp = 'outer'; }
2{ let tmp = 'inner'; console.log(tmp); }
--- orig.js	2026-10-22 14:25:52.582623525 -0400
+++ fixed.js	2026-10-22 14:25:55.738764672 -0400
@@ -1,2 +1,2 @@
-{ let tmp = 'outer'; }
-{ let tmp = 'inner'; console.log(tmp); }
+{ const tmp = 'outer'; }
+{ const tmp = 'inner'; console.log(tmp); }
inner
r2-p006 · asi-semicolonless-leading-paren-bracket
1let x = 1
2(function(){ console.log('IIFE:', x); })()
--- orig.js	2026-10-22 14:25:52.583623569 -0400
+++ fixed.js	2026-10-22 14:25:56.910817104 -0400
@@ -1,2 +1,2 @@
-let x = 1
+const x = 1
 (function(){ console.log('IIFE:', x); })()
r2-p007 · class-fields-static-blocks-private-names-super
1class Base {
2 static { let s = 1; console.log('Base static:', s); }
3}
4class Der extends Base {
5 static { let s = 2; console.log('Der static:', s); }
6 constructor() { super(); console.log('Der instance:'); }
7}
8new Der();
--- orig.js	2026-10-22 14:25:55.189740114 -0400
+++ fixed.js	2026-10-22 14:25:57.810857373 -0400
@@ -1,8 +1,8 @@
 class Base {
-  static { let s = 1; console.log('Base static:', s); }
+  static { const s = 1; console.log('Base static:', s); }
 }
 class Der extends Base {
-  static { let s = 2; console.log('Der static:', s); }
+  static { const s = 2; console.log('Der static:', s); }
   constructor() { super(); console.log('Der instance:'); }
 }
 new Der();
Base static: 1
Der static: 2
Der instance:
r2-p008 · var-hoisting-redeclaration-inside-loops-after-use
1for (var i = 0; i < 2; i++) {
2 let j = i;
3 console.log('i:', i, 'j:', j);
4}
5console.log('final i:', i);
--- orig.js	2026-10-22 14:25:56.865815090 -0400
+++ fixed.js	2026-10-22 14:26:00.636866486 -0400
@@ -1,5 +1,5 @@
 for (var i = 0; i < 2; i++) {
-  let j = i;
+  const j = i;
   console.log('i:', i, 'j:', j);
 }
 console.log('final i:', i);
i: 0 j: 0
i: 1 j: 1
final i: 2