apple/pkl · error · ParserError

unexpectedTokenForExpression

unexpectedTokenForExpression

Error message

Unexpected token `{0}`.

What it means

Expression-level parse failure without a specific expectation: a token appeared where an expression was required (or where no particular token was mandated). The parser throws "Unexpected token `{0}`" when it cannot continue parsing an expression and has no expectation to report.

Solutions

  1. Remove the offending token if it's stray punctuation (`;`, `,`, `)` that has no opener).
  2. Supply the missing expression (e.g. after `=` or an operator that ended the previous line).
  3. Insert the intended operator between two juxtaposed expressions (`+`, `.`, whitespace-amend only where valid).
  4. Check the previous line for an accidentally deleted operator or operand that shifted tokens out of place.

Example fix

// before
x =
y = 2
// after
x = 1
y = 2
Defensive patterns

Strategy: try-catch

Validate before calling

// Flag lines that begin with tokens that cannot start an expression
const BAD_EXPR_START = /^\s*[),;]+|^[*/%]|^&&|^\|\|/;
function linesNotStartingAnExpression(lines) {
  return lines.map((l, i) => [l, i]).filter(([l]) => BAD_EXPR_START.test(l)).map(([, i]) => i + 1);
}

Try / catch

try {
  return parsePkl(src);
} catch (e) {
  if (/^Unexpected token `/.test(e.message) && !/Expected `/.test(e.message)) {
    throw new Error('Expression expected near ' + e.span + ': remove stray punctuation or supply the missing operand: ' + e.message);
  }
  throw e;
}

Prevention

When it happens

Trigger: Starting a line with a token that cannot begin an expression (e.g. `)`, `,`, `=>`, an operator like `*` or `&&`); two expressions juxtaposed without an operator; malformed constructs such as `x = ;` or an empty right-hand side of `=`.

Common situations: Stray commas or semicolons carried over from JSON/Java habits; accidentally deleting the right-hand side of an assignment; line-continuation mistakes where an operator from the previous line was dropped.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/ee83d4cf4c78eb98. Report an issue: GitHub.

Appendix: source

Thrown at pkl-parser/src/main/java/org/pkl/parser/ParserImpl.java:1047

            if (lookahead == Token.LPAREN
                && !precededBySemicolon
                && _lookahead.newLinesBetween == 0) {
              var args = parseArgumentList();
              yield new UnqualifiedAccessExpr(
                  identifier, args, identifier.span().endWith(args.span()));
            } else {
              yield new UnqualifiedAccessExpr(identifier, null, identifier.span());
            }
          }
          case EOF ->
              throw new ParserError(
                  ErrorMessages.create("unexpectedEndOfFile"), prev.span.stopSpan().move(1));
          default -> {
            var text = _lookahead.text(lexer);
            if (expectation != null) {
              throw parserError("unexpectedToken", text, expectation);
            }
            throw parserError("unexpectedTokenForExpression", text);
          }
        };
    return parseExprRest(expr);
  }

  @SuppressWarnings("DuplicatedCode")
  private Expr parseExprRest(Expr expr) {
    // non-null
    if (lookahead == Token.NON_NULL) {
      var end = next().span;
      var res = new NonNullExpr(expr, expr.span().endWith(end));
      return parseExprRest(res);
    }
    // amends
    if (lookahead == Token.LBRACE) {
      if (expr instanceof ParenthesizedExpr
          || expr instanceof AmendsExpr
          || expr instanceof NewExpr) {

View on GitHub (pinned to f3efcbfc9b)