apple/pkl · error
Unexpected character
Error message
Unexpected character `{0}`. Did you mean `{1}`, `{2}` or `{3}`? What it means
The lexer sees a `.` starting a dot-sequence that does not form a valid token. Valid forms are `.` (member access), `..` (range), `...` (spread), `...?` (null-safe spread), and `..` followed by digits (number like `1.5` handled elsewhere). Anything else, e.g. `.?` or `....`, triggers unexpectedChar with the four valid suggestions.
Solutions
- If optional access was intended, note Pkl uses `?.` on method/reference syntax differently — check docs and use the supported form.
- Fix the spread syntax: use `...` or `...?` exactly.
- Use a single `.` for member access or `..` for ranges.
- Remove the extra/stray dot characters.
Example fix
// before (TypeScript habit) foo?.bar // after foo?.bar // only if supported in your Pkl version; otherwise: foo.bar
Defensive patterns
Strategy: validation
Validate before calling
function assertValidDotSequence(src) {
const bad = src.match(/\.{4,}|\.\?|\.\.\?\?|\.\./g);
// allow '..' ranges but flag '.?' and 4+ dots
const illegal = src.match(/\.\?|\.{4,}/);
if (illegal) throw new Error(`Invalid dot sequence '${illegal[0]}' at index ${illegal.index}`);
} Prevention
- Memorize the valid forms: `.`, `..`, `...`, `...?`.
- Do not assume TypeScript `?.` chaining exists in Pkl; verify against current docs.
- Lint generated code for accidental double-doubled dots.
When it happens
Trigger: Writing malformed dot sequences such as `.?`, `. …` mixing characters, `..*`, or an accidental extra dot in spread/range syntax — e.g. `....` or `..?`.
Common situations: Typos in null-safe spread (`...?` written as `..?`); optional chaining habits from TypeScript (`?.`) typed into Pkl; hand-written range expressions missing a bound.
Related errors
- Unexpected character
- invalidCharacter
- unexpectedEndOfFile
- '" + ch + "'
- closingStringDelimiterMustBeginOnNewLine
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/5c0384f50b0de726.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-parser/src/main/java/org/pkl/parser/Lexer.java:237
nextChar();
yield Token.INT_DIV;
} else {
throw unexpectedChar(ch, "~/");
}
}
case '.' -> {
if (lookahead == '.') {
nextChar();
if (lookahead == '.') {
nextChar();
if (lookahead == '?') {
nextChar();
yield Token.QSPREAD;
} else {
yield Token.SPREAD;
}
} else {
throw unexpectedChar("..", ".", "...", "...?");
}
} else if (lookahead >= '0' && lookahead <= '9') {
yield lexNumber(ch);
} else {
yield Token.DOT;
}
}
case '`' -> {
lexQuotedIdentifier();
yield Token.IDENTIFIER;
}
case '/' -> lexSlash();
case '"' -> lexStringStart(0);
case '#' -> {
if (lookahead == '!') {
yield lexShebang();
} else {
yield lexStringStartPounds();View on GitHub (pinned to f3efcbfc9b)