{"record":{"id":"c8aabb7f235a9135","repo":"toon-format/toon","slug":"invalid-escape-sequence-backslash-at-end-of-strin","errorCode":null,"errorMessage":"Invalid escape sequence: backslash at end of string","messagePattern":"Invalid escape sequence: backslash at end of string","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"packages/toon/src/shared/string-utils.ts","lineNumber":55,"sourceCode":"    .replace(/\\t/g, `${BACKSLASH}t`)\n    // eslint-disable-next-line no-control-regex\n    .replace(/[\\u0000-\\u001F]/g, c => `${BACKSLASH}u${c.charCodeAt(0).toString(16).padStart(4, '0')}`)\n}\n\n/**\n * Unescapes a string by processing escape sequences.\n *\n * @remarks\n * Lone surrogates in `\\uXXXX` escapes are rejected.\n */\nexport function unescapeString(value: string): string {\n  let unescaped = ''\n  let i = 0\n\n  while (i < value.length) {\n    if (value[i] === BACKSLASH) {\n      if (i + 1 >= value.length) {\n        throw new SyntaxError('Invalid escape sequence: backslash at end of string')\n      }\n\n      const next = value[i + 1]\n      if (next === 'n') {\n        unescaped += NEWLINE\n        i += 2\n        continue\n      }\n      if (next === 't') {\n        unescaped += TAB\n        i += 2\n        continue\n      }\n      if (next === 'r') {\n        unescaped += CARRIAGE_RETURN\n        i += 2\n        continue\n      }","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/toon-format/toon/blob/604eac266e35166bed6f5b9e3bd586e9c60a9330/packages/toon/src/shared/string-utils.ts#L37-L73","documentation":"unescapeString processes backslash escapes in parsed TOON string literals. If the input ends with a bare backslash, there is no following character to complete an escape sequence, so the parser throws a SyntaxError rather than silently dropping or keeping the backslash.","triggerScenarios":"Parsing TOON input (via parseStringLiteral or key parsing) where a quoted string literal ends with `\"...\\\\\"` — a backslash as the last character before the closing quote.","commonSituations":"Hand-edited TOON files with Windows-style paths like \"C:\\\\dir\\\\\" mis-escaped; truncated files or strings clipped mid-escape by text processing or templating tools.","solutions":["Double the trailing backslash so it is a valid escaped backslash (\\\\)","Remove the dangling backslash if it was unintended","Check the source file for truncation and regenerate it from the encoder"],"exampleFix":"// before (in TOON input)\npath: \"C:\\\\Users\\\\\"\n// after\npath: \"C:\\\\Users\\\\\\\\\"","handlingStrategy":"try-catch","validationCode":"function hasTrailingBackslash(s: string): boolean {\n  const m = s.match(/\\\\\\\\$/)\n  return m !== null && (m.index === 0 || (s.slice(0, m.index).match(/\\\\\\\\*$/)?.[0].length ?? 0) % 2 === 1)\n}","typeGuard":null,"tryCatchPattern":"try {\n  const value = decode(input)\n} catch (e) {\n  if (e instanceof SyntaxError && e.message.includes('backslash at end of string')) {\n    // repair: double the trailing backslash and retry once\n  }\n  throw e\n}","preventionTips":["Always escape literal backslashes as \\\\ in hand-written TOON","Avoid manual string surgery on encoded TOON text","Validate round-trip: decode(encode(x)) === x in tests"],"tags":["decoder","escape-sequence","syntax-error","string-parsing"],"backgroundTag":"invalid-escape-sequence","analyzedSha":"604eac266e35166bed6f5b9e3bd586e9c60a9330","analyzedAt":"2026-08-31T11:09:25.043Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}