apple/pkl · error · GenericParserError

unexpectedCurlyProbablyAmendsExpression

unexpectedCurlyProbablyAmendsExpression

Error message

Unexpected token: `'{'`. If you meant to write an amends expression, wrap the parent in parentheses. Try: `({0}) '{' ... '}'`

What it means

A `{` appeared where an expression result cannot be amended: the parsed expression was not parenthesized, an amends, or a new expression. Pkl suggests wrapping the base expression in parentheses if an amends was intended, since `foo{...}` is otherwise ambiguous/invalid.

Solutions

  1. Wrap the base expression in parentheses: `(expr) { ... }`
  2. Use `new` for fresh objects: `new { ... }` instead of `expr { ... }`
  3. Remove the `{ ... }` block if no amends was intended

Example fix

// before
let (x = base) x { port = 1 }
// after
(base) { port = 1 }
// or
new { port = 1 }
Defensive patterns

Strategy: validation

Validate before calling

/[^\s)\]]\s*\{/.test(src) // suspicious '{' directly after a non-parenthesized expression — prefer '(expr) {' or 'new {'

Prevention

When it happens

Trigger: parseExprRest sees Token.LBRACE after an expression whose node type is none of PARENTHESIZED_EXPR, AMENDS_EXPR, NEW_EXPR — e.g. `x.y * 2 { ... }` or a plain identifier from a non-amendable parse path.

Common situations: Trying to amend a function call or computed value without parentheses; intending object-literal syntax from another language (JSON/JS) where `{}` follows any expression; forgetting `new` before an object body.

Understand the failure class

Related errors


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

Appendix: source

Thrown at pkl-parser/src/main/java/org/pkl/parser/GenericParserImpl.java:927

          }
        };
    return parseExprRest(expr);
  }

  @SuppressWarnings("DuplicatedCode")
  private Node parseExprRest(Node expr) {
    // amends
    if (lookahead() == Token.LBRACE) {
      var children = new ArrayList<Node>();
      children.add(expr);
      ff(children);
      if (expr.type == NodeType.PARENTHESIZED_EXPR
          || expr.type == NodeType.AMENDS_EXPR
          || expr.type == NodeType.NEW_EXPR) {
        children.add(parseObjectBody());
        return parseExprRest(new Node(NodeType.AMENDS_EXPR, children));
      }
      throw parserError("unexpectedCurlyProbablyAmendsExpression", expr.text(lexer.getSource()));
    }
    return expr;
  }

  private boolean isFunctionLiteral() {
    var originalCursor = cursor;
    try {
      next(); // open (
      ff();
      var token = next().token;
      ff();
      if (token == Token.RPAREN) {
        return lookahead == Token.ARROW;
      }
      if (token == Token.UNDERSCORE) {
        return true;
      }
      if (token != Token.IDENTIFIER) {

View on GitHub (pinned to f3efcbfc9b)