biome suspicious/noUselessEscapeInString
labelled safe
Analysis Nemotron 3 Super
The rule flags unnecessary escape sequences in regular string literals where escaping a character has no semantic effect.
Fix: Remove the backslash before the escaped character, leaving the character itself unchanged in the string literal.
8 hazards
- In a regex literal like /\a/, removing the backslash changes the pattern to /a/, altering matching behavior.
- If the escaped character is part of a larger escape sequence like \\n, removing one backslash incorrectly yields \n instead of preserving the intended literal backslash followed by 'n'.
- In a string used with eval or Function constructor, altering escapes could change the resulting code's syntax or semantics when evaluated.
- If the string contains a comment-like sequence such as /* or // after fix insertion, it could inadvertently create or break a comment in the source if the string is later interpreted as code.
- When the string is concatenated with other strings involving line continuations via backslash-newline, removing a backslash could break the line continuation and cause a syntax error.
- If the escaped character appears in a template literal section that is passed to a tag function, the tag may rely on the raw escape presence for custom processing, so removing it alters the tag's input.
- In JSX attribute values, although the rule ignores JSX strings, if a similar fix were applied incorrectly, it could change how the attribute value is parsed by the JSX transformer.
- If the string is used as a key in object property access via bracket notation and the escaped character was relied upon for obfuscation or specific encoding, removing the escape could expose or alter the key unexpectedly.
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | fix ok | Arguments object and length interaction | arguments object, function.length, default parameters, rest parameters |
| r1-p002 | silent prediction off | Block-scoped function declaration | function declarations inside blocks, switch cases, labeled statements |
| r1-p003 | fix ok | Strict mode coercion difference | strict vs sloppy mode semantics |
| r1-p004 | fix ok | RegExp lastIndex mutation with g flag | regular expressions: escapes, unicode flag, lastIndex with the g flag |
| r1-p005 | silent prediction off | Tagged template literal dependency | If the escaped character appears in a template literal section that is passed to a tag function, the tag may rely on the raw escape presence for custom processing, so removing it alters the tag's inpu |
| r1-p006 | fix ok | Bracket notation key obfuscation | If the string is used as a key in object property access via bracket notation and the escaped character was relied upon for obfuscation or specific encoding, removing the escape could expose or alter |
| r1-p007 | silent prediction off | Getter side effect dependency | getters, setters and Object.defineProperty side effects |
| r1-p008 | fix ok prediction off | Name shadowing after rewrite | name collisions across scopes after a move (shadowing) |
| r2-p001 | silent prediction off | Regex literal backslash removal alters match | In a regex literal like /\a/, removing the backslash changes the pattern to /a/, altering matching behavior. |
| r2-p002 | silent prediction off | Getter side effect dependency | getters, setters and Object.defineProperty side effects |
| r2-p003 | silent prediction off | Eval with altered escape changes code semantics | In a string used with eval or Function constructor, altering escapes could change the resulting code's syntax or semantics when evaluated. |
| r2-p004 | silent | JSX attribute value misinterpretation | In JSX attribute values, although the rule ignores JSX strings, if a similar fix were applied incorrectly, it could change how the attribute value is parsed by the JSX transformer. |
| r2-p005 | silent prediction off | Bracket notation key obfuscation exposure | If the string is used as a key in object property access via bracket notation and the escaped character was relied upon for obfuscation or specific encoding, removing the escape could expose or alter |
| r2-p006 | silent prediction off | Var hoisting and redeclaration in loop | var hoisting and re-declaration inside loops or after use |
| r2-p007 | silent prediction off | Line continuation via backslash-newline broken | When the string is concatenated with other strings involving line continuations via backslash-newline, removing a backslash could break the line continuation and cause a syntax error. |
| r2-p008 | silent prediction off | Numeric/string coercion with toString/valueOf | numeric/string coercion: + vs template literal, objects with toString/valueOf, Symbol, BigInt |
Sources
r1-p001 · Arguments object and length interaction
1function f(a='\a', ...rest) {
2 return [arguments.length, arguments[0], f.length];
3}
4console.log(f());
--- orig.js 2026-10-17 17:12:56.323895451 -0400 +++ fixed.js 2026-10-17 17:12:56.597868285 -0400 @@ -1,4 +1,4 @@ -function f(a='\a', ...rest) { +function f(a='a', ...rest) { return [arguments.length, arguments[0], f.length]; } console.log(f());
[ 0, undefined, 0 ]
r1-p002 · Block-scoped function declaration
1{ function g() { return '\b'; }
2 console.log(g());
3}
r1-p003 · Strict mode coercion difference
1"use strict";
2try {
3 eval('\c');
4} catch (e) {
5 console.log(e.name + ': ' + e.message);
6}
--- orig.js 2026-10-17 17:12:56.990829323 -0400 +++ fixed.js 2026-10-17 17:12:57.264802206 -0400 @@ -1,6 +1,6 @@ "use strict"; try { - eval('\c'); + eval('c'); } catch (e) { console.log(e.name + ': ' + e.message); }
ReferenceError: c is not defined
r1-p004 · RegExp lastIndex mutation with g flag
1const re = /\d/g;
2re.lastIndex = 0;
3console.log(re.exec('1\a2')[0]);
4console.log(re.lastIndex);
--- orig.js 2026-10-17 17:12:57.441784691 -0400 +++ fixed.js 2026-10-17 17:12:57.718757279 -0400 @@ -1,4 +1,4 @@ const re = /\d/g; re.lastIndex = 0; -console.log(re.exec('1\a2')[0]); +console.log(re.exec('1a2')[0]); console.log(re.lastIndex);
1 1
r1-p005 · Tagged template literal dependency
1function tag(strings) {
2 return strings.raw[0].length;
3}
4console.log(tag`hello\aworld`);
12
r1-p006 · Bracket notation key obfuscation
1const map = {'\d': 42};
2console.log(map['\d']);
--- orig.js 2026-10-17 17:12:58.095719990 -0400 +++ fixed.js 2026-10-17 17:12:58.368693025 -0400 @@ -1,2 +1,2 @@ -const map = {'\d': 42}; -console.log(map['\d']); +const map = {'d': 42}; +console.log(map['d']);
42
r1-p007 · Getter side effect dependency
1const obj = {
2 get getValue() {
3 return this._value + '\f';
4 }
5};
6obj._value = 'start';
7console.log(obj.getValue);
start
r1-p008 · Name shadowing after rewrite
1let x = 1;
2if (true) {
3 const x = '\g';
4 console.log(x);
5}
6console.log(x);
--- orig.js 2026-10-17 17:12:58.762654108 -0400 +++ fixed.js 2026-10-17 17:12:59.034627248 -0400 @@ -1,6 +1,6 @@ let x = 1; if (true) { - const x = '\g'; + const x = 'g'; console.log(x); } console.log(x);
g 1
r2-p001 · Regex literal backslash removal alters match
1const s = '\\a';
2const re = new RegExp(s);
3console.log(re.test('a'));
true
r2-p002 · Getter side effect dependency
1let val = '';
2Object.defineProperty({}, 'x', {
3 get() { return val += '\\a'; }
4});
5try {
6 ({}.x);
7} catch(e) {}
8console.log(val);
r2-p003 · Eval with altered escape changes code semantics
1const code = 'return \\a;';
2let result;
3try { result = eval(code); } catch(e) { result = e.message; }
4console.log(result);
Illegal return statement
r2-p004 · JSX attribute value misinterpretation
1console.log('jsx-ignore');
jsx-ignore
r2-p005 · Bracket notation key obfuscation exposure
1const map = {'\\a': 42};
2console.log(map['\\a']);
42
r2-p006 · Var hoisting and redeclaration in loop
1for (var i = 0; i < 1; i++) {
2 var msg = '\\a';
3}
4console.log(msg);
\a
r2-p007 · Line continuation via backslash-newline broken
1let s = 'hello' +
2 '\\' +
3 'world';
4console.log(s);
hello\world
r2-p008 · Numeric/string coercion with toString/valueOf
1const obj = {
2 toString() { return '\\a'; }
3};
4console.log(String(obj));
\a