{"record":{"id":"07d9a90f81a3ea5c","repo":"apple/pkl","slug":"unexpectedcharacter","errorCode":"unexpectedCharacter","errorMessage":"Unexpected character `{0}`. Did you mean `{1}`?","messagePattern":"Unexpected character `(.+?)`\\. Did you mean `(.+?)`\\?","errorType":"exception","errorClass":"ParserError","httpStatus":null,"severity":"error","filePath":"pkl-parser/src/main/java/org/pkl/parser/Lexer.java","lineNumber":495,"sourceCode":"              c - 2,\n              cursor - c + 2);\n\n        throw lexError(\n            ErrorMessages.create(\"invalidCharacterEscapeSequence\", \"\\\\\" + (char) ch, \"\\\\\"),\n            c - 2,\n            2);\n      }\n      default ->\n          throw lexError(\n              ErrorMessages.create(\"invalidCharacterEscapeSequence\", \"\\\\\" + (char) ch, \"\\\\\"),\n              cursor - 2,\n              2);\n    };\n  }\n\n  private Token lexUnicodeEscape() {\n    if (lookahead != '{') {\n      throw unexpectedChar(lookahead, \"{\");\n    }\n    do {\n      nextChar();\n    } while (lookahead != '}' && lookahead != EOF && Character.isLetterOrDigit(lookahead));\n    if (lookahead == '}') {\n      // consume the close bracket\n      nextChar();\n    } else {\n      throw lexError(ErrorMessages.create(\"unterminatedUnicodeEscapeSequence\", text()), span());\n    }\n    return Token.STRING_ESCAPE_UNICODE;\n  }\n\n  private Token lexIdentifier() {\n    while (isIdentifierPart(lookahead)) {\n      nextChar();\n    }\n","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-parser/src/main/java/org/pkl/parser/Lexer.java#L477-L513","documentation":"A unicode escape `\\u` must be followed by `{codepoint}` in braces. When the lexer reaches lexUnicodeEscape and the lookahead is not `{`, it throws unexpectedCharacter suggesting `{`. This means the `u` of `\\u` was consumed (via lexEscape) but the required opening brace is missing or replaced by something else.","triggerScenarios":"lexEscape → lexUnicodeEscape: the string contains `\\u` followed by a character other than `{`, e.g. `\\u0041`, `\\u41`, or `\\u\"`. Only `\\u{...}` is valid.","commonSituations":"Habit from Java/Python/C where `\\u0041` or `\\uXXXX` is the standard syntax; converting escapes from JSON (`\\u0041`) into Pkl; truncation where `{` was deleted leaving `\\u` before a letter or quote.","solutions":["Wrap the codepoint in braces: `\\u{41}` instead of `\\u41`.","Re-check every `\\u` in the file and ensure each is followed by `{`.","If a literal `u` was meant, escape the backslash: `\\\\u`.","For fixed 4-digit escapes coming from JSON, convert programmatically to the braced form."],"exampleFix":"// before\narrow = \"\\u2192\"\n// after\narrow = \"\\u{2192}\"","handlingStrategy":"validation","validationCode":"function unbracedUnicode(src) { return /\\\\u(?!\\{)/.test(src); }\nif (unbracedUnicode(src)) throw new Error('Unicode escapes must be \\u{...}, not \\uXXXX');","typeGuard":"null","tryCatchPattern":"try { tokens = lexer.next(); } catch (e) { if (e.code === 'unexpectedCharacter' && /\\\\u/.test(e.message ?? '')) { console.error('Wrap unicode codepoint in braces: \\u{...}'); } throw e; }","preventionTips":["Convert JSON-style \\uXXXX escapes when moving configs into Pkl.","Search sources for \\u not followed by { before parsing.","Use \\u{41} braced form exclusively in your team's style guide.","Escape a literal backslash-u as \\\\u."],"tags":["lexer","pkl","unicode","escape-sequence"],"backgroundTag":"invalid-escape-sequence","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}