biome style/noUnusedTemplateLiteral
labelled safe
Analysis Nemotron 3 Super
The rule flags template literals without interpolations or escaped characters as unused.
Fix: Replace the template literal with a string literal using single quotes, preserving the exact content inside the backticks.
5 hazards
- If the template literal contains a backslash followed by a quote (e.g., `it\'`s`), rewriting to a single-quoted string may create an invalid escape or alter the string value due to differing escape rules.
- If the template literal contains a backtick character (e.g., `a\(b\)`), removing backticks and using single quotes may cause syntax errors if the content includes unescaped single quotes or breaks string delimiters.
- If the template literal is part of a larger expression like `` `Hello ${user}` + `!` ``, the autofix only applies to the unused part, but if misapplied to the whole, it would break interpolation — however, the rule only flags fully unused literals, so this is mitigated by scope.
- If the template literal is tagged (e.g., `html`<p>text</p>`), the rule does not fire because it’s considered used via the tag, so no fix is attempted — hence no hazard from misapplying fix to tagged literals.
- If the template literal appears in a directive prologue (e.g., `
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | fix ok | arguments-object-shadowed-by-template | arguments object interaction when fixing unused template literal in nested scope |
| r1-p002 | fix ok prediction off | regex-escape-in-unicode-mode-gflag | Regex \u escape behavior depends on raw string content; fix may alter meaning if template contains backslashes |
| r1-p003 | silent | tagged-template-not-affected-hazard-near-miss | Near-miss: tagged template looks unused but rule does not fire due to tag usage |
| r1-p004 | fix ok | var-hoisting-redeclaration-loop-interaction | var hoisting + loop re-declaration: fix removes initializer but declaration remains, affecting TDZ-like behavior via hoisting |
| r1-p005 | fix ok | async-await-generator-yield-position | Unused template in async function after await - fix removal changes control flow if expression had side effects |
| r1-p006 | fix ok | getter-setter-defineproperty-side-effect | Setter invokes fixed template expression - removing it eliminates side effect |
| r1-p007 | fix ok | exception-in-fixed-expression | Exception thrown during evaluation of template literal (if it had side effects in expression) - but static templates don't throw... so make it seem like it could |
| r1-p008 | fix ok | sparse-array-hole-vs-dense | Template literal in array literal - fix changes value but array hole vs dense behavior differs if used in iteration |
| r2-p001 | silent prediction off | Unicode Escape Behavior Depends on Raw String | regex-escape-in-unicode-mode-gflag |
| r2-p002 | silent prediction off | Arrow Function this Binding Captures Outer Scope | this-binding |
| r2-p003 | fix ok | Backtick Inside Template Causes Syntax Error When Rewritten | backtick-character-breaking-string-delimiters |
| r2-p004 | fix ok | Directive Prologue Usage | directive-prologue |
| r2-p005 | silent prediction off | var Hoisting and Loop Re-declaration Interaction | var-hoisting-redeclaration-loop-interaction |
| r2-p006 | silent prediction off | Name Collision Across Scopes After Shadowing | name-collisions-across-scopes-after-a-move |
| r2-p007 | fix ok | Temporal Dead Zone After Hoisting | temporal-dead-zone-after-code-is-hoisted-or-reordered |
| r2-p008 | silent prediction off | arguments Object Interaction in Nested Scope | arguments-object-shadowed-by-template |
Sources
r1-p001 · arguments-object-shadowed-by-template
1function outer(a) {
2 const b = `arg is ${a}`;
3 function inner() {
4 console.log(arguments[0]); // expects 'inner'
5 const c = `static`; // triggers rule
6 console.log(c); // prints static before fix, but after fix still works...
7 return c;
8 }
9 console.log(inner());
10}
11outer('x');
--- orig.js 2026-10-17 16:57:54.586816991 -0400 +++ fixed.js 2026-10-17 16:57:54.881820987 -0400 @@ -2,7 +2,7 @@ const b = `arg is ${a}`; function inner() { console.log(arguments[0]); // expects 'inner' - const c = `static`; // triggers rule + const c = "static"; // triggers rule console.log(c); // prints static before fix, but after fix still works... return c; }
undefined static static
r1-p002 · regex-escape-in-unicode-mode-gflag
1const pattern = `\\d`; // actually '\d' due to double escaping
2const re = new RegExp(pattern, 'ug');
3console.log(re.test('a')); // false
4console.log(re.test('1')); // true
5// rule does NOT fire because pattern has backslash -> escaped char
--- orig.js 2026-10-17 16:57:55.057823370 -0400 +++ fixed.js 2026-10-17 16:57:55.340827202 -0400 @@ -1,4 +1,4 @@ -const pattern = `\\d`; // actually '\d' due to double escaping +const pattern = "\\d"; // actually '\d' due to double escaping const re = new RegExp(pattern, 'ug'); console.log(re.test('a')); // false console.log(re.test('1')); // true
false true
r1-p003 · tagged-template-not-affected-hazard-near-miss
1function html(strings) {
2 return strings.raw.join('');
3}
4const result = html`<div>content</div>`;
5console.log(result); // <div>content</div>
6// Rule silent because tagged -> considered used
<div>content</div>
r1-p004 · var-hoisting-redeclaration-loop-interaction
1for (let i = 0; i < 2; i++) {
2 var x = `loop` + i; // first iter: 'loop0', second: 'loop1'
3 if (i === 0) {
4 var x = `inner`; // re-declaration, same var, re-initialized
5 console.log(x); // prints 'inner' then 'inner' again?
6 }
7 console.log(x); // after if: 'inner' both times due to hoisting
8}
--- orig.js 2026-10-17 16:57:55.752832779 -0400 +++ fixed.js 2026-10-17 16:57:56.029836529 -0400 @@ -1,7 +1,7 @@ for (let i = 0; i < 2; i++) { - var x = `loop` + i; // first iter: 'loop0', second: 'loop1' + var x = "loop" + i; // first iter: 'loop0', second: 'loop1' if (i === 0) { - var x = `inner`; // re-declaration, same var, re-initialized + var x = "inner"; // re-declaration, same var, re-initialized console.log(x); // prints 'inner' then 'inner' again? } console.log(x); // after if: 'inner' both times due to hoisting
inner inner loop1
r1-p005 · async-await-generator-yield-position
1async function seq() {
2 const x = await Promise.resolve(1);
3 console.log(x); // 1
4 const y = `unused`; // triggers rule
5 console.log(y); // 'unused'
6 return y;
7}
8seq().then(r => console.log('result:', r));
--- orig.js 2026-10-17 16:57:56.197838802 -0400 +++ fixed.js 2026-10-17 16:57:56.475842563 -0400 @@ -1,7 +1,7 @@ async function seq() { const x = await Promise.resolve(1); console.log(x); // 1 - const y = `unused`; // triggers rule + const y = "unused"; // triggers rule console.log(y); // 'unused' return y; }
1 unused result: unused
r1-p006 · getter-setter-defineproperty-side-effect
1const obj = {};
2let log = '';
3Object.defineProperty(obj, 'prop', {
4 set(v) { log += v; }
5});
6obj.prop = `side` + `effect`; // first: template with interpolation? No -> 'sideeffect' is two statics
7// Actually: `side` + `effect` -> two template literals, both trigger rule
8// After fix: becomes 'side' + 'effect' -> same value
9// But we want one static template
10let captured = `static`; // triggers
11obj.prop = captured;
12console.log(log); // should be 'static'
--- orig.js 2026-10-17 16:57:56.647844890 -0400 +++ fixed.js 2026-10-17 16:57:56.938848827 -0400 @@ -3,10 +3,10 @@ Object.defineProperty(obj, 'prop', { set(v) { log += v; } }); -obj.prop = `side` + `effect`; // first: template with interpolation? No -> 'sideeffect' is two statics +obj.prop = "side" + "effect"; // first: template with interpolation? No -> 'sideeffect' is two statics // Actually: `side` + `effect` -> two template literals, both trigger rule // After fix: becomes 'side' + 'effect' -> same value // But we want one static template -let captured = `static`; // triggers +let captured = "static"; // triggers obj.prop = captured; console.log(log); // should be 'static'
sideeffectstatic
r1-p007 · exception-in-fixed-expression
1try {
2 const x = `hello`; // triggers rule
3 console.log(x);
4 throw new Error('from after');
5} catch (e) {
6 console.log(e.name + ': ' + e.message);
7}
8console.log('end');
--- orig.js 2026-10-17 16:57:57.104851073 -0400 +++ fixed.js 2026-10-17 16:57:57.377854764 -0400 @@ -1,5 +1,5 @@ try { - const x = `hello`; // triggers rule + const x = "hello"; // triggers rule console.log(x); throw new Error('from after'); } catch (e) {
hello Error: from after end
r1-p008 · sparse-array-hole-vs-dense
1const arr = [, `hole`, `static`]; // index 0: hole, 1: 'hole', 2: 'static'
2console.log(arr.length); // 3
3arr.forEach((v, i) => {
4 if (v === undefined) console.log('hole at', i);
5 else console.log(i, v);
6});
--- orig.js 2026-10-17 16:57:57.545857036 -0400 +++ fixed.js 2026-10-17 16:57:57.815860686 -0400 @@ -1,4 +1,4 @@ -const arr = [, `hole`, `static`]; // index 0: hole, 1: 'hole', 2: 'static' +const arr = [, "hole", "static"]; // index 0: hole, 1: 'hole', 2: 'static' console.log(arr.length); // 3 arr.forEach((v, i) => { if (v === undefined) console.log('hole at', i);
3 1 hole 2 static
r2-p001 · Unicode Escape Behavior Depends on Raw String
1const pattern = 'hello\\u{1F600}world'; // u-flag needs raw \u{...}
2const regexStr = `\\${pattern}`; // Template: raw backslashes preserved
3try {
4 const r = new RegExp(regexStr, 'gu');
5 console.log(r.test('hello😀world'));
6} catch (e) {
7 console.log(e.name + ': ' + e.message);
8}
SyntaxError: Invalid regular expression: /\hello\u{1F600}world/gu: Invalid escaper2-p002 · Arrow Function this Binding Captures Outer Scope
1const obj = { value: 42 };
2const getValue = () => `this.value is ${this.value}`;
3const bound = getValue.bind(obj);
4console.log(bound());
r2-p003 · Backtick Inside Template Causes Syntax Error When Rewritten
1let s = `a\`b`; // Template literal containing escaped backtick
2console.log(s); // Should print: a`b
3// After fix: becomes 'a`b' → invalid due to unescaped backtick in single quotes
--- orig.js 2026-10-17 16:58:04.055944891 -0400 +++ fixed.js 2026-10-17 16:58:04.322948486 -0400 @@ -1,3 +1,3 @@ -let s = `a\`b`; // Template literal containing escaped backtick +let s = "a\`b"; // Template literal containing escaped backtick console.log(s); // Should print: a`b // After fix: becomes 'a`b' → invalid due to unescaped backtick in single quotes
a`b
r2-p004 · Directive Prologue Usage
1'use strict';
2`use asm`;
3function f() {
4 return 5;
5}
6console.log(f());
--- orig.js 2026-10-17 16:58:04.486950695 -0400 +++ fixed.js 2026-10-17 16:58:04.761954398 -0400 @@ -1,5 +1,5 @@ 'use strict'; -`use asm`; +"use asm"; function f() { return 5; }
5
r2-p005 · var Hoisting and Loop Re-declaration Interaction
1for (var i = 0; i < 2; i++) {
2 var msg = `count: ${i}`;
3 console.log(msg);
4}
5console.log(typeof msg); // Should be 'string' due to hoisting
count: 0 count: 1 string
r2-p006 · Name Collision Across Scopes After Shadowing
1let x = 1;
2if (true) {
3 const x = `inner: ${x}`; // Rule triggers here
4 console.log(x);
5}
6console.log(x); // Should print 1
r2-p007 · Temporal Dead Zone After Hoisting
1console.log(typeof y); // TDZ: should error
2let y = `tdz value`;
3console.log(y);
--- orig.js 2026-10-17 16:58:05.369962582 -0400 +++ fixed.js 2026-10-17 16:58:05.649966351 -0400 @@ -1,3 +1,3 @@ console.log(typeof y); // TDZ: should error -let y = `tdz value`; +let y = "tdz value"; console.log(y);
r2-p008 · arguments Object Interaction in Nested Scope
1function f() {
2 function g() {
3 const args = `args: ${arguments.length}`;
4 console.log(args);
5 }
6 g();
7}
8f(1, 2, 3);
args: 0