apple/pkl · error
missingDelimiter
missingDelimiter
Error message
Missing `{0}` delimiter. What it means
A string literal was opened but the matching closing delimiter (a `"` preceded by the same number of `#` as the opening) was never found on the same line. Pkl single-line strings cannot contain raw newlines, so when the lexer hits a newline or carriage return inside the string body it throws missingDelimiter. The expected delimiter text includes the `#` repetition for multi-line `#"..."#` strings.
Source
Thrown at pkl-parser/src/main/java/org/pkl/parser/Lexer.java:354
return Token.STRING_MULTI_START;
}
private void lexStringEnd(InterpolationScope scope) {
// don't actually need to check it here
for (var i = 0; i < scope.quotes + scope.pounds; i++) {
nextChar();
}
}
private void lexString(int pounds) {
var poundsInARow = 0;
var foundQuote = false;
var foundBackslash = false;
while (lookahead != EOF) {
var ch = nextChar();
switch (ch) {
case '\n', '\r' ->
throw lexError(
ErrorMessages.create("missingDelimiter", "\"" + "#".repeat(pounds)), cursor - 1, 1);
case '"' -> {
if (pounds == 0) {
backup();
stringEnded = true;
return;
}
foundQuote = true;
foundBackslash = false;
poundsInARow = 0;
}
case '\\' -> {
foundQuote = false;
foundBackslash = true;
poundsInARow = 0;
if (pounds == poundsInARow) {
backup(pounds + 1);
isEscape = true;View on GitHub (pinned to f3efcbfc9b)
Solutions
- Add the closing `"` (with the same `#` prefix if opened as `#"`) on the same line.
- Use a multi-line string (`"""` form) if the value must span lines.
- Escape the newline with `\` line continuation or use string concatenation (`+`).
- Check for a stray unmatched quote earlier in the line that swallowed the real closing quote.
Example fix
// before greeting = "hello world" // after greeting = """ hello world """
Defensive patterns
Strategy: validation
Validate before calling
function singleLineStringsClosed(line) { const q = (line.match(/(?<!\\)"/g) || []).length; return q % 2 === 0; }
if (!pklLines.every(singleLineStringsClosed)) throw new Error('Unbalanced quotes in single-line string'); Type guard
null
Try / catch
try { tokens = lexer.next(); } catch (e) { if (e.code === 'missingDelimiter') { console.error(`Unterminated string at line ${e.line}`); } throw e; } Prevention
- Use triple-quoted """ strings for values spanning multiple lines.
- Enable editor highlighting for string literals to spot unterminated strings.
- Check # counts match on both ends of #-delimited strings.
- Never put raw newlines inside single-line string literals.
When it happens
Trigger: nextString → lexString: while scanning the body of a string, the lexer reaches a `\n` or `\r` before encountering the closing `"` (with matching `#` pounds), or encounters EOF. Any raw line break inside a single-line string literal triggers it.
Common situations: Forgetting to close a string before pressing Enter; intending a multi-line string but writing `"...` instead of `"""...` (triple-quote) form; copy-paste splitting a long string across lines without concatenation; mismatched `#` counts between opening and closing of `#"..."#`.
Related errors
- unterminatedUnicodeEscapeSequence
- invalidUnicodeEscapeSequence
- type mismatch: value is not the expected string literal
- type mismatch: value is not one of the expected string liter
- invalidLineContinuationEscapeSequence
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/b649aba762870917.
Report an issue: GitHub.