fixhunt

eslint no-regex-spaces

labelled safe
Runs / 2026-10-22T18-18-44-853Z-8ihx-eslint-no-regex-spaceseslint 9.39.52026-10-22 18:18 UTC8 programs × 2 round(s)16 programs, 13 fired, 13 fixed, 2 findings, 1 rejectedmodel cost $0.02

Analysis Nemotron 3 Super

Flags regex patterns containing two or more consecutive literal spaces.

Fix: Replaces every maximal sequence of N ≥ 2 literal spaces inside a regex pattern with '{N}' (e.g., ' ' → '{3}'), preserving quotes and flags.

1 hazards
  • The fix assumes the pattern is a literal string; if the regex is built via concatenation or variables, the autofix may corrupt non-literal parts.], [

Findings

programoraclelabeljudgestatussummary
r1-p004fix-changes-behaviorlabelled safeprogram-bug · lowrelatedThe program attempts to call a regular expression literal as a function, which throws a TypeError both before and after the fix. The behavioral difference is c…
r2-p005fix-changes-behaviorlabelled safeprogram-bug · lowrelatedThe program fails before the fix with a TypeError because the regex literal is immediately followed by `.test` without a semicolon, causing the parser to treat…

Programs

idresulttitlehazard
r1-p001invalidFunction declaration nested in block with repeated callfunction declarations inside blocks, switch cases, labeled statements
r1-p002fix okArguments object accessing parameter after regex-dependent shiftarguments object, function.length, default parameters, rest parameters
r1-p003fix ok__proto__ key mutation affecting regex lookup via prototype chain__proto__ keys, prototype access, Object.assign vs spread
r1-p004fix-changes-behaviorASI hazard: leading paren misparsed as function call after regexASI and semicolon-less code, leading ( or [ on the next line
r1-p005silentRegex built via concatenation: fix corrupts variable partThe fix assumes the pattern is a literal string; if the regex is built via concatenation or variables, the autofix may corrupt non-literal parts.
r1-p006fix okVar hoisting and redeclaration inside loop after regex usevar hoisting and re-declaration inside loops or after use
r1-p007fix okUnicode flag and lastIndex interaction with g flag after fixregular expressions: escapes, unicode flag, lastIndex with the g flag
r1-p008silent prediction offException thrown in closure capturing rewritten regexexceptions thrown inside the code the fix removes or rewrites
r2-p001fix okSparse Arrays Holes Interactionsparse arrays, holes, Array(n) vs [n], array-likes
r2-p002fix ok__proto__ Key Mutation Prototype Lookup__proto__ keys, prototype access, Object.assign vs spread
r2-p003fix okVar Hoisting Redefinition Loop After Usevar hoisting and re-declaration inside loops or after use
r2-p004fix okOrder of Evaluation Merged Duplicated Deleted Side Effectsorder of evaluation when expressions are merged, duplicated or deleted (side effects run twice or never)
r2-p005fix-changes-behaviorASI Semicolon-less Leading Paren Bracket Next LineASI and semicolon-less code, leading ( or [ on the next line
r2-p006fix okComments Attached to Removed Moved Codecomments attached to the removed or moved code
r2-p007fix okGetters Setters DefineProperty Side Effectsgetters, setters and Object.defineProperty side effects
r2-p008fix okNull Undefined Distinction Optional Chaining Nullishnull/undefined distinction, optional chaining short-circuit, nullish vs falsy

Sources

r1-p001 · Function declaration nested in block with repeated call (generated program does not terminate within the time limit)
1if (true) {
2 let count = 0;
3 function f() { return /a b/.test('a b'); }
4 do {
5 if (f()) count++;
6 } while (count < 2);
7}
8console.log(count);
r1-p002 · Arguments object accessing parameter after regex-dependent shift
1function g(x, y = /x y\s+/.test('x y')) {
2 if (arguments.length === 2 && arguments[1]) return arguments[0] + 1;
3 return 0;
4}
5console.log(g(5));
--- orig.js	2026-10-22 14:18:52.486908933 -0400
+++ fixed.js	2026-10-22 14:18:55.757032769 -0400
@@ -1,4 +1,4 @@
-function g(x, y = /x    y\s+/.test('x   y')) {
+function g(x, y = /x {4}y\s+/.test('x   y')) {
   if (arguments.length === 2 && arguments[1]) return arguments[0] + 1;
   return 0;
 }
0
r1-p003 · __proto__ key mutation affecting regex lookup via prototype chain
1const base = { getPat: () => /test{2,} end/ };
2const obj = { __proto__: base };
3obj.getPat = () => /test{2,} end/;
4let hits = 0;
5for (let i = 0; i < 2; i++) {
6 if (obj.getPat().test('testxx end')) hits++;
7}
8console.log(hits);
--- orig.js	2026-10-22 14:18:52.486908933 -0400
+++ fixed.js	2026-10-22 14:18:56.372056100 -0400
@@ -1,6 +1,6 @@
-const base = { getPat: () => /test{2,}  end/ };
+const base = { getPat: () => /test{2,} {2}end/ };
 const obj = { __proto__: base };
-obj.getPat = () => /test{2,}  end/;
+obj.getPat = () => /test{2,} {2}end/;
 let hits = 0;
 for (let i = 0; i < 2; i++) {
   if (obj.getPat().test('testxx  end')) hits++;
0
r1-p004 · ASI hazard: leading paren misparsed as function call after regex
1let x = /'hello world'/
2(['a','b']).forEach(c => { if (/^h/.test(c)) x = null })
3console.log(x === null ? 'failed' : x.source)
--- orig.js	2026-10-22 14:18:52.487908971 -0400
+++ fixed.js	2026-10-22 14:18:56.208049877 -0400
@@ -1,3 +1,3 @@
-let x = /'hello   world'/
+let x = /'hello {3}world'/
 (['a','b']).forEach(c => { if (/^h/.test(c)) x = null })
 console.log(x === null ? 'failed' : x.source)
r1-p005 · Regex built via concatenation: fix corrupts variable part
1const spacer = ' ';
2const pat = new RegExp('foo' + spacer + 'bar');
3console.log(pat.test('foo bar') ? 'ok' : 'bad');
ok
r1-p006 · Var hoisting and redeclaration inside loop after regex use
1function scopeTest() {
2 if (true) {
3 var v = 1;
4 if (/pattern{1,3} tail/.test('patternxx tail')) v = 2;
5 {
6 var v = 3;
7 console.log(v);
8 }
9 }
10}
11scopeTest();
--- orig.js	2026-10-22 14:18:52.489909047 -0400
+++ fixed.js	2026-10-22 14:18:54.628990012 -0400
@@ -1,7 +1,7 @@
 function scopeTest() {
   if (true) {
     var v = 1;
-    if (/pattern{1,3}   tail/.test('patternxx   tail')) v = 2;
+    if (/pattern{1,3} {3}tail/.test('patternxx   tail')) v = 2;
     {
       var v = 3;
       console.log(v);
3
r1-p007 · Unicode flag and lastIndex interaction with g flag after fix
1let re = /\s+ \d+/gu;
2re.lastIndex = 0;
3let m1 = re.exec('a 5');
4let m2 = re.exec('a 5');
5console.log(m1 ? m1.index : -1, m2 ? m2.index : -1);
--- orig.js	2026-10-22 14:18:55.680029850 -0400
+++ fixed.js	2026-10-22 14:18:58.910152509 -0400
@@ -1,4 +1,4 @@
-let re = /\s+  \d+/gu;
+let re = /\s+ {2}\d+/gu;
 re.lastIndex = 0;
 let m1 = re.exec('a  5');
 let m2 = re.exec('a  5');
-1 -1
r1-p008 · Exception thrown in closure capturing rewritten regex
1let fails = 0;
2try {
3 [/start \t middle/].forEach(r => {
4 if (!r.test('start\t\tmiddle')) throw new Error('no match');
5 });
6} catch (e) {
7 fails++;
8 console.log(e.name, e.message);
9}
10console.log(fails);
Error no match
1
r2-p001 · Sparse Arrays Holes Interaction
1const arr = [];
2arr[0] = /a b/.test('a b');
3arr[2] = /x y/.test('x y');
4console.log(arr.length, arr[0], arr[1], arr[2]);
--- orig.js	2026-10-22 14:19:13.256701362 -0400
+++ fixed.js	2026-10-22 14:19:15.872802139 -0400
@@ -1,4 +1,4 @@
 const arr = [];
-arr[0] = /a  b/.test('a  b');
-arr[2] = /x    y/.test('x    y');
+arr[0] = /a {2}b/.test('a  b');
+arr[2] = /x {4}y/.test('x    y');
 console.log(arr.length, arr[0], arr[1], arr[2]);
3 true undefined true
r2-p002 · __proto__ Key Mutation Prototype Lookup
1let obj = { __proto__: null };
2obj.__proto__ = { test: /hello world/.test('hello world') };
3const copy = Object.assign({}, obj);
4console.log(copy.test);
--- orig.js	2026-10-22 14:19:13.256701362 -0400
+++ fixed.js	2026-10-22 14:19:17.029846777 -0400
@@ -1,4 +1,4 @@
 let obj = { __proto__: null };
-obj.__proto__ = { test: /hello  world/.test('hello  world') };
+obj.__proto__ = { test: /hello {2}world/.test('hello  world') };
 const copy = Object.assign({}, obj);
 console.log(copy.test);
true
r2-p003 · Var Hoisting Redefinition Loop After Use
1for (var i = 0; i < 2; i++) {
2 if (i === 0) var pattern = /test case/;
3 console.log(pattern.test('test case'));
4}
5console.log(typeof pattern);
--- orig.js	2026-10-22 14:19:13.257701401 -0400
+++ fixed.js	2026-10-22 14:19:17.069848322 -0400
@@ -1,5 +1,5 @@
 for (var i = 0; i < 2; i++) {
-  if (i === 0) var pattern = /test  case/;
+  if (i === 0) var pattern = /test {2}case/;
   console.log(pattern.test('test  case'));
 }
 console.log(typeof pattern);
true
true
object
r2-p004 · Order of Evaluation Merged Duplicated Deleted Side Effects
1let count = 0;
2function side() { return ++count; }
3console.log((/a b/.test('a b'), side()) + (side(), /x y/.test('x y')));
--- orig.js	2026-10-22 14:19:13.257701401 -0400
+++ fixed.js	2026-10-22 14:19:17.025846623 -0400
@@ -1,3 +1,3 @@
 let count = 0;
 function side() { return ++count; }
-console.log((/a  b/.test('a  b'), side()) + (side(), /x    y/.test('x    y')));
+console.log((/a {2}b/.test('a  b'), side()) + (side(), /x {4}y/.test('x    y')));
2
r2-p005 · ASI Semicolon-less Leading Paren Bracket Next Line
1let x = /hello world/.test('hello world')
2
3(() => { console.log('IIFE ran'); })()
4console.log(x);
--- orig.js	2026-10-22 14:19:13.258701439 -0400
+++ fixed.js	2026-10-22 14:19:17.125850484 -0400
@@ -1,4 +1,4 @@
-let x = /hello  world/.test('hello  world')
+let x = /hello {2}world/.test('hello  world')
 
 (() => { console.log('IIFE ran'); })()
 console.log(x);
r2-p006 · Comments Attached to Removed Moved Code
1// Keep this
2/pattern match/
3// Important comment
4console.log(/pattern match/.test('pattern match'));
--- orig.js	2026-10-22 14:19:13.258701439 -0400
+++ fixed.js	2026-10-22 14:19:17.022846507 -0400
@@ -1,4 +1,4 @@
 // Keep this
-/pattern  match/
+/pattern {2}match/
 // Important comment
-console.log(/pattern  match/.test('pattern  match'));
+console.log(/pattern {2}match/.test('pattern  match'));
true
r2-p007 · Getters Setters DefineProperty Side Effects
1let obj = {};
2Object.defineProperty(obj, 'prop', {
3 get: () => /test value/.test('test value'),
4 enumerable: true
5});
6console.log(obj.prop);
--- orig.js	2026-10-22 14:19:17.472863883 -0400
+++ fixed.js	2026-10-22 14:19:21.205008194 -0400
@@ -1,6 +1,6 @@
 let obj = {};
 Object.defineProperty(obj, 'prop', {
-  get: () => /test  value/.test('test  value'),
+  get: () => /test {2}value/.test('test  value'),
   enumerable: true
 });
 console.log(obj.prop);
true
r2-p008 · Null Undefined Distinction Optional Chaining Nullish
1let value = null;
2console.log(value?.match(/a b/));
3value = undefined;
4console.log(value?.match(/a b/) ?? 'nullish');
--- orig.js	2026-10-22 14:19:18.656909621 -0400
+++ fixed.js	2026-10-22 14:19:21.288011409 -0400
@@ -1,4 +1,4 @@
 let value = null;
-console.log(value?.match(/a  b/));
+console.log(value?.match(/a {2}b/));
 value = undefined;
-console.log(value?.match(/a  b/) ?? 'nullish');
+console.log(value?.match(/a {2}b/) ?? 'nullish');
undefined
nullish