apple/pkl · error
unexpectedEndOfFile
unexpectedEndOfFile
Error message
Unexpected end of file.
What it means
While lexing the start of a custom-delimiter string (a `#` opening a `#"..."#` style string), lexStringStartPounds() reaches EOF before finding the opening quote. Since the string never begins, the lexer throws unexpectedEndOfFile. This guards `#...#` multi-pound custom string syntax against truncated input.
Solutions
- Complete the custom string: follow the `#`s with `"` and close with `"` plus the same number of `#`s, e.g. `#"text"#`.
- If a comment was intended, use `//` or `///` instead of `#`.
- Check the file for truncation and restore the missing content.
Example fix
// before pattern = #\d+# // after pattern = #"\d+"#
Defensive patterns
Strategy: validation
Validate before calling
function validateCustomStrings(src) {
// every run of #'s must be followed (eventually) by a quote before EOF
const re = /#+(?!["\/#])/g;
let m;
while ((m = re.exec(src))) {
throw new Error(`'#' at index ${m.index} does not start a comment or custom string`);
}
} Prevention
- Close custom strings with matching pound count: `#"..."#`, `##"..."##`.
- Use `//` or `///` for comments — `#` is not a Pkl comment marker.
- Verify generated files end with the expected closing delimiters before publishing.
When it happens
Trigger: Source contains `#`, `##`, etc. (starting a custom string) but the file ends before a `"` follows — e.g. a `#"""..."""#` string whose content was cut off, or a lone `#` at end of file.
Common situations: Truncated file from failed save/download; heredoc or template script that dropped the rest of the string; regex-like `#` comments written assuming `#` starts a comment (Pkl uses `///` or `//` for comments, not `#`).
Related errors
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/079eb9af60d1f57f.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-parser/src/main/java/org/pkl/parser/Lexer.java:312
return Token.STRING_NEWLINE;
}
if (lookahead == '\n') {
nextChar();
return Token.STRING_NEWLINE;
}
lexMultiString(scope.pounds);
}
return Token.STRING_PART;
}
private Token lexStringStartPounds() {
int pounds = 1;
while (lookahead == '#') {
nextChar();
pounds++;
}
if (lookahead == EOF) {
throw lexError(ErrorMessages.create("unexpectedEndOfFile"), span());
}
if (lookahead != '"') {
throw unexpectedChar(lookahead, "\"");
}
nextChar();
return lexStringStart(pounds);
}
private Token lexStringStart(int pounds) {
var quotes = 1;
if (lookahead == '"') {
nextChar();
if (lookahead == '"') {
nextChar();
quotes = 3;
} else {
backup();
}View on GitHub (pinned to f3efcbfc9b)