{"record":{"id":"2aa70cb0915d4987","repo":"toon-format/toon","slug":"invalid-escape-sequence-u-must-be-followed-by-4","errorCode":null,"errorMessage":"Invalid escape sequence: \\u must be followed by 4 hex digits, got \"${hex}\"","messagePattern":"Invalid escape sequence: \\\\u must be followed by 4 hex digits, got \"(.+?)\"","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"packages/toon/src/shared/string-utils.ts","lineNumber":90,"sourceCode":"        continue\n      }\n      if (next === BACKSLASH) {\n        unescaped += BACKSLASH\n        i += 2\n        continue\n      }\n      if (next === DOUBLE_QUOTE) {\n        unescaped += DOUBLE_QUOTE\n        i += 2\n        continue\n      }\n      if (next === 'u') {\n        if (i + 6 > value.length) {\n          throw new SyntaxError(`Invalid escape sequence: truncated \\\\u escape at \"${value.slice(i, i + 6)}\"`)\n        }\n        const hex = value.slice(i + 2, i + 6)\n        if (!/^[0-9a-f]{4}$/i.test(hex)) {\n          throw new SyntaxError(`Invalid escape sequence: \\\\u must be followed by 4 hex digits, got \"${hex}\"`)\n        }\n        const codeUnit = Number.parseInt(hex, 16)\n        if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {\n          throw new SyntaxError(`Invalid escape sequence: \\\\u${hex} is a lone surrogate. Supplementary code points MUST appear as literal UTF-8`)\n        }\n        unescaped += String.fromCodePoint(codeUnit)\n        i += 6\n        continue\n      }\n\n      throw new SyntaxError(`Invalid escape sequence: \\\\${next}`)\n    }\n\n    unescaped += value[i]\n    i++\n  }\n\n  return unescaped","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/toon-format/toon/blob/604eac266e35166bed6f5b9e3bd586e9c60a9330/packages/toon/src/shared/string-utils.ts#L72-L108","documentation":"After \\u, the next 4 characters must be hexadecimal digits. If they are not (e.g. \\uZZZZ or \\u 12), unescapeString throws this SyntaxError reporting the offending 4-character slice.","triggerScenarios":"Parsing a quoted TOON string containing \\u followed by 4 non-hex characters, e.g. \"\\u1G3F\" or \"\\u hEL\".","commonSituations":"Hand-written escapes with typos; strings converted from formats allowing surrogate-pair escapes; generated input where placeholders leaked into \\u sequences.","solutions":["Correct the escape to exactly 4 hex digits 0-9/a-f/A-F","Replace the escape with the literal UTF-8 character","Escape non-ASCII content when encoding rather than hand-writing \\u escapes"],"exampleFix":"// before (TOON input)\nname: \"\\u1G3F\"\n// after\nname: \"\\u1F3F\"  // or the literal emoji character","handlingStrategy":"validation","validationCode":"function hasValidUnicodeEscapes(s: string): boolean {\n  return !/\\\\u(?:(?![0-9a-fA-F]{4})|(?![0-9a-fA-F]{4}))/i.test(s.replace(/\\\\u[0-9a-fA-F]{4}/g, ''))\n}","typeGuard":null,"tryCatchPattern":"try {\n  const value = decode(input)\n} catch (e) {\n  if (e instanceof SyntaxError && e.message.includes('4 hex digits')) {\n    // extract offending hex from message, correct, retry\n  }\n  throw e\n}","preventionTips":["Generate \\u escapes programmatically rather than typing them","Use a JSON-aware converter that validates escapes before producing TOON","Add CI linting for /\\\\u(?![0-9a-fA-F]{4})/ in TOON fixtures"],"tags":["decoder","escape-sequence","unicode","hex"],"backgroundTag":"invalid-escape-sequence","analyzedSha":"604eac266e35166bed6f5b9e3bd586e9c60a9330","analyzedAt":"2026-08-31T11:09:25.043Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}