{"record":{"id":"179dc10cd9dd7e22","repo":"apple/pkl","slug":"invalidunicodeescapesequence","errorCode":"invalidUnicodeEscapeSequence","errorMessage":"Invalid Unicode escape sequence `{text}`.\n\nValid Unicode escape sequences are {prefix}'{'0'}' to {prefix}'{'10FFFF'}' (1-6 hexadecimal characters).","messagePattern":"Invalid Unicode escape sequence `(.+?)`\\.\n\nValid Unicode escape sequences are (.+?)'(.+?)' to (.+?)'(.+?)' \\(1-6 hexadecimal characters\\)\\.","errorType":"error_code","errorClass":"ParserError","httpStatus":null,"severity":"error","filePath":"pkl-parser/src/main/java/org/pkl/parser/ParserImpl.java","lineNumber":1664,"sourceCode":"      case STRING_ESCAPE_QUOTE -> \"\\\"\";\n      case STRING_ESCAPE_BACKSLASH -> \"\\\\\";\n      case STRING_ESCAPE_TAB -> \"\\t\";\n      case STRING_ESCAPE_RETURN -> \"\\r\";\n      case STRING_ESCAPE_CONTINUATION -> \"\";\n      case STRING_ESCAPE_UNICODE -> parseUnicodeEscape(tk);\n      default -> throw new RuntimeException(\"Unreacheable code\");\n    };\n  }\n\n  private String parseUnicodeEscape(FullToken tk) {\n    var text = tk.text(lexer);\n    var lastIndex = text.length() - 1;\n    var startIndex = text.indexOf('{', 2);\n    try {\n      var codepoint = Integer.parseInt(text.substring(startIndex + 1, lastIndex), 16);\n      return Character.toString(codepoint);\n    } catch (NumberFormatException e) {\n      throw new ParserError(\n          ErrorMessages.create(\"invalidUnicodeEscapeSequence\", text, text.substring(0, startIndex)),\n          tk.span);\n    }\n  }\n\n  private String getCommonIndent(List<TempNode> nodes, Span span) {\n    var lastNode = nodes.get(nodes.size() - 1);\n    if (lastNode.token == null) {\n      throw new ParserError(\n          ErrorMessages.create(\"closingStringDelimiterMustBeginOnNewLine\"), lastNode.span());\n    }\n    if (lastNode.token.token == Token.STRING_NEWLINE) return \"\";\n    var beforeLast = nodes.get(nodes.size() - 2);\n    if (beforeLast.token != null && beforeLast.token.token == Token.STRING_NEWLINE) {\n      var indent = getTrailingIndent(lastNode);\n      if (indent != null) {\n        return indent;\n      }","sourceCodeStart":1646,"sourceCodeEnd":1682,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-parser/src/main/java/org/pkl/parser/ParserImpl.java#L1646-L1682","documentation":"Pkl string escapes use the form `\\u{XXXXXX}` with 1–6 hexadecimal digits (code points up to 10FFFF). The parser decodes the escape by parsing the hex substring between braces with Integer.parseInt(radix 16); if that fails (invalid characters, empty body, or a code point out of range caught as NumberFormatException) it throws invalidUnicodeEscapeSequence, echoing the full offending text and the escape prefix, at the token's span.","triggerScenarios":"Parsing a string containing a malformed `\\u{...}` escape: non-hex characters inside the braces (`\\u{12G4}`), nothing between the braces (`\\u{}`), more than 6 hex digits (`\\u{0010FFFF0}`), or a value beyond U+10FFFF such that Character.toString also fails.","commonSituations":"Copying `\\uXXXX` escapes from JSON/Java (no braces) into Pkl; hand-typing escapes and mistyping a hex digit; generating escapes programmatically with a decimal code point instead of hex.","solutions":["Fix the escape to 1–6 hexadecimal digits inside braces, e.g. `\\u{1F600}`","Convert non-hex characters to valid hex digits (e.g. use `\\u{41}` instead of `\\u{G}`)","Ensure the code point is ≤ 10FFFF; split surrogate pairs into single code points","If migrating from Java/JSON, transform `\\uXXXX` to Pkl's braced form `\\u{XXXX}`"],"exampleFix":"// before\ns = \"\\u{12G4}\"\n// after\ns = \"\\u{12F4}\"","handlingStrategy":"validation","validationCode":"function validPklUnicodeEscapes(src) {\n  return [...src.matchAll(/\\\\u\\{([^}]*)\\}/g)].every(([, hex]) =>\n    /^[0-9a-fA-F]{1,6}$/.test(hex) && parseInt(hex, 16) <= 0x10FFFF\n  );\n}\n// validate every \\u{...} escape has 1-6 hex digits and value <= 10FFFF before parsing","typeGuard":"null","tryCatchPattern":"try {\n  const result = parser.parse(source);\n} catch (e) {\n  if (e.errorId === 'invalidUnicodeEscapeSequence') {\n    // correct the escape flagged in e.getMessage() at e.span\n  } else { throw e; }\n}","preventionTips":["Convert \\uXXXX (Java/JSON) escapes to Pkl's \\u{XXXX} braced form","Validate hex digits programmatically when generating escapes","Emit code points, not surrogate pairs, and cap at U+10FFFF"],"tags":["parser","pkl","unicode","escape-sequence","string-literal"],"backgroundTag":"invalid-unicode-escape","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}