apple/pkl · error · GenericParserError
multipleUnionDefaults
multipleUnionDefaults
Error message
A type union cannot have more than one default type.
What it means
Within one type union, at most one member may carry the default marker `*`. parseType tracks hasDefault; when a second `*` is seen while parsing union members, it throws multipleUnionDefaults. A union default must be unambiguous to be usable in Pkl's type inference and amending semantics.
Solutions
- Keep exactly one `*` member; remove `*` from all but the intended default.
- Decide which member should be the default and mark only that one.
- Search the union declaration for repeated `*` occurrences.
Example fix
// before x: *"a"|*"b" // after x: *"a"|"b"
Defensive patterns
Strategy: validation
Validate before calling
// At most one `*` default marker per union
function singleUnionDefault(typeExpr) {
return (typeExpr.match(/\*/g) || []).length <= 1;
} Prevention
- Decide the default member first, then add `|member` entries without `*`.
- Avoid templates that stamp `*` onto every union member.
- Review unions after bulk type edits for duplicated markers.
When it happens
Trigger: Writing a union like `*"a"|*"b"` where two members both start with `*`.
Common situations: Editing a union and accidentally duplicating the `*` prefix when adding a member; bulk-replacing types that each had their own default; macros/templating that prepend `*` to every member.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- notAUnion
- Cannot parse ` ` as number.
- cannotAmendLocalPropertyDefinition
- cannotDefineExternalMember
- cannotFindMember
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/760be0affc2781c2.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-parser/src/main/java/org/pkl/parser/GenericParserImpl.java:1146
var first = parseTypeAtom(expectation);
children.add(first);
if (lookahead() != Token.UNION) {
if (hasDefault) {
//noinspection ConstantValue (NullAway needs this assertion, IntelliJ doesn't)
assert start != null;
throw parserError(ErrorMessages.create("notAUnion"), start.endWith(first.span));
}
return first;
}
while (lookahead() == Token.UNION) {
ff(children);
children.add(makeTerminal(next()));
ff(children);
if (lookahead == Token.STAR) {
if (hasDefault) {
throw parserError("multipleUnionDefaults");
}
children.add(makeTerminal(next()));
ff(children);
hasDefault = true;
}
var type = parseTypeAtom(expectation);
children.add(type);
}
return new Node(NodeType.UNION_TYPE, children);
}
private Node parseTypeAtom(@Nullable String expectation) {
var typ =
switch (lookahead) {
case UNKNOWN -> make(NodeType.UNKNOWN_TYPE, next().span);
case NOTHING -> make(NodeType.NOTHING_TYPE, next().span);
case MODULE -> make(NodeType.MODULE_TYPE, next().span);
case THIS -> make(NodeType.THIS_TYPE, next().span);View on GitHub (pinned to f3efcbfc9b)