{"record":{"id":"a6e7d5aae64ac516","repo":"karatelabs/karate","slug":"invalid-escape-sequence-in-template-literal-esc","errorCode":null,"errorMessage":"invalid escape sequence in template literal: \\<esc>","messagePattern":"invalid escape sequence in template literal: \\\\<esc>","errorType":"exception","errorClass":"io.karatelabs.parser.ParserException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/parser/JsLexer.java","lineNumber":391,"sourceCode":"            c = peek();\n            if (c == '`') {\n                break;\n            }\n            if (c == '$' && peek(1) == '{') {\n                break;\n            }\n            if (c == '\\\\') {\n                advance();\n                if (isAtEnd()) {\n                    break;\n                }\n                char esc = peek();\n                // Spec: in non-tagged template literals, malformed escape sequences are\n                // early errors. We have no way to tell tag vs no-tag at lex time, so we\n                // reject at lex time; tagged templates are not yet supported anyway.\n                // Invalid legacy octal: \\1..\\9 or \\0 followed by a decimal digit.\n                if (esc >= '1' && esc <= '9') {\n                    throw new ParserException(\"invalid escape sequence in template literal: \\\\\" + esc);\n                }\n                if (esc == '0' && peek(1) >= '0' && peek(1) <= '9') {\n                    throw new ParserException(\"invalid escape sequence in template literal: \\\\0\" + peek(1));\n                }\n                // Hex escape backslash-x HH — require exactly two hex digits.\n                if (esc == 'x') {\n                    if (!isHexDigit(peek(1)) || !isHexDigit(peek(2))) {\n                        throw new ParserException(\"invalid hex escape sequence in template literal\");\n                    }\n                }\n                // Unicode escape backslash-u HHHH or backslash-u {H...} — require proper form.\n                if (esc == 'u') {\n                    char next = peek(1);\n                    if (next == '{') {\n                        // backslash-u { codepoint } — one or more hex digits, closed by }\n                        int j = 2;\n                        if (!isHexDigit(peek(j))) {\n                            throw new ParserException(\"invalid unicode escape sequence in template literal\");","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/parser/JsLexer.java#L373-L409","documentation":"In a template literal (backtick string), a backslash followed by digit 1-9 is an invalid legacy octal escape; the ES spec makes malformed escapes early errors in untagged templates, so JsLexer rejects them at lex time. Fix the escape or double-escape if you intended a literal backslash.","triggerScenarios":"A non-tagged template literal in JS evaluated by karate-js contains an escape like \\1 through \\9, e.g. `col \\1` or a regex fragment pasted into a template string; hit in scanTemplateContent (JsLexer.java:391).","commonSituations":"Copy-pasting regex replacement patterns ($1, \\1) into template literals, Windows path fragments like `C:\\temp\\2`, porting old octal escapes from other languages, string-building code that interpolates numbers right after a backslash.","solutions":["Remove the invalid escape or correct it (use \\0 for NUL, or \\x01 / \\u0001 for codepoint 1)","Escape the backslash itself: write \\\\1 in the template literal to mean backslash followed by 1","Move regex-replacement patterns into actual RegExp context instead of a template literal","Use a plain single-quoted string with proper escaping if no interpolation is needed"],"exampleFix":"// before\nvar s = `match group: \\1`;\n// after\nvar s = `match group: \\\\1`; // or use a real regex replacement context","handlingStrategy":"validation","validationCode":"// reject invalid template escapes before handing the string to eval\nfunction hasBadTemplateEscapes(tl) {\n  return /\\\\[1-9]/.test(tl) || /\\\\0[0-9]/.test(tl);\n}\nif (hasBadTemplateEscapes(tpl)) throw new Error('invalid legacy octal escape in template literal');","typeGuard":"null","tryCatchPattern":"try {\n  karate.eval('var s = `' + tpl + '`;');\n} catch (e) {\n  if (String(e.message).indexOf('invalid escape sequence in template literal') >= 0) {\n    tpl = tpl.replace(/\\\\/g, '\\\\\\\\'); // escape all backslashes and retry\n  } else throw e;\n}","preventionTips":["Never paste regex replacement patterns (\\1, $1) into template literals","Double backslashes when you mean a literal backslash in any JS string","Prefer \\xNN / \\uNNNN forms over legacy octal escapes","Lint templates with a JS parser before dynamic evaluation"],"tags":["javascript","lexer","template-literal","escape-sequence"],"backgroundTag":"invalid-escape-sequence","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}