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

  1. Complete the custom string: follow the `#`s with `"` and close with `"` plus the same number of `#`s, e.g. `#"text"#`.
  2. If a comment was intended, use `//` or `///` instead of `#`.
  3. 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

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)