apple/pkl · error · ParserError
unexpectedTokenForType
unexpectedTokenForType
Error message
Unexpected token `)`. Expected a type.
What it means
While parsing a parenthesized type expression, the parser hit the closing `)` as the first token inside the parentheses, meaning no type was found where one was required. It throws unexpectedTokenForType with `)` as the offending token when the child-type list is empty; if types had been parsed, the same `)` would simply close a ParenthesizedType.
Solutions
- Remove the empty `()` if no type was intended
- For zero-argument function types, check the Pkl version — upgrade the parser/amplifier to one supporting `() -> T`, or use a placeholder parameter type if unsupported
- Complete the type expression inside the parentheses, e.g. `foo: (String)` or `(String) -> Int`
Example fix
// before f: () -> String // after (if empty param lists unsupported) f: (nothing) -> String // or upgrade to a parser supporting () -> T
Defensive patterns
Strategy: try-catch
Validate before calling
function checkEmptyTypeParens(src) {
return !/\(\s*\)/.test(src.replace(/"(?:\\.|[^"])*"/g, '')); // ignore string literals
}
// reject empty '()' in type positions before invoking the parser (unless targeting a parser that supports () -> T) Type guard
null
Try / catch
try {
const result = parser.parseType(source);
} catch (e) {
if (e.errorId === 'unexpectedTokenForType') {
// fill in the missing type inside the parentheses or upgrade the parser
} else { throw e; }
} Prevention
- Never leave `()` placeholders in type annotations
- Check parser/version support for zero-argument function types `() -> T`
- Use IDE completion for type syntax to avoid empty parens
When it happens
Trigger: Parsing source containing an empty type parenthesis, e.g. `foo: ()` in a type position, `List<()>`, or a function type written as `() -> String` being parsed in a context where the parser does not accept the zero-argument parameter list form (the `)` arrives with no children collected yet).
Common situations: Writing a zero-argument function type `() -> String` against an older parser that expects at least one parameter type; typos like `Map<,>` or `()` placeholders left in unfinished code.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ErrorMessages.create(errorKey, args)
- unexpectedToken
- unexpectedTokenForExpression
- Cannot parse ` ` as number.
- cannotAmendLocalPropertyDefinition
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/4823387d804e47af.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-parser/src/main/java/org/pkl/parser/ParserImpl.java:1412
case THIS -> typ = new Type.ThisType(next().span);
case LPAREN -> {
var tk = next();
var children = new ArrayList<Node>();
Span end;
if (lookahead == Token.RPAREN) {
end = next().span;
} else {
children.addAll(parseListOf(Token.COMMA, Token.RPAREN, () -> parseType(")")));
end = expect(Token.RPAREN, "unexpectedToken2", ",", ")").span;
}
if (lookahead == Token.ARROW || children.size() > 1) {
expect(Token.ARROW, "unexpectedToken", "->");
var ret = parseType(expectation);
children.add(ret);
typ = new Type.FunctionType(children, tk.span.endWith(ret.span()));
} else {
if (children.isEmpty()) {
throw new ParserError(ErrorMessages.create("unexpectedTokenForType", ")"), end);
}
typ = new ParenthesizedType((Type) children.get(0), tk.span.endWith(end));
}
}
case IDENTIFIER -> {
var start = spanLookahead;
var name = parseQualifiedIdentifier();
var end = name.span();
TypeArgumentList typeArgumentList = null;
if (lookahead == Token.LT) {
typeArgumentList = parseTypeArgumentList();
end = typeArgumentList.span();
}
typ = new DeclaredType(name, typeArgumentList, start.endWith(end));
}
case STRING_START -> {
var str = parseStringConstant();
typ = new StringConstantType(str, str.span());View on GitHub (pinned to f3efcbfc9b)