{"record":{"id":"0ca2e2686445eabc","repo":"apple/pkl","slug":"notaunion-0ca2e2","errorCode":"notAUnion","errorMessage":"Only type unions can have a default marker (*).","messagePattern":"Only type unions can have a default marker \\(\\*\\)\\.","errorType":"exception","errorClass":"GenericParserError","httpStatus":null,"severity":"error","filePath":"pkl-parser/src/main/java/org/pkl/parser/GenericParserImpl.java","lineNumber":1135,"sourceCode":"  private Node parseType(@Nullable String expectation) {\n    var children = new ArrayList<Node>();\n    var hasDefault = false;\n    FullSpan start = null;\n    if (lookahead == Token.STAR) {\n      var tk = next();\n      start = tk.span;\n      children.add(makeTerminal(tk));\n      ff(children);\n      hasDefault = true;\n    }\n    var first = parseTypeAtom(expectation);\n    children.add(first);\n\n    if (lookahead() != Token.UNION) {\n      if (hasDefault) {\n        //noinspection ConstantValue (NullAway needs this assertion, IntelliJ doesn't)\n        assert start != null;\n        throw parserError(ErrorMessages.create(\"notAUnion\"), start.endWith(first.span));\n      }\n      return first;\n    }\n\n    while (lookahead() == Token.UNION) {\n      ff(children);\n      children.add(makeTerminal(next()));\n      ff(children);\n      if (lookahead == Token.STAR) {\n        if (hasDefault) {\n          throw parserError(\"multipleUnionDefaults\");\n        }\n        children.add(makeTerminal(next()));\n        ff(children);\n        hasDefault = true;\n      }\n      var type = parseTypeAtom(expectation);\n      children.add(type);","sourceCodeStart":1117,"sourceCodeEnd":1153,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-parser/src/main/java/org/pkl/parser/GenericParserImpl.java#L1117-L1153","documentation":"Pkl's `*` token marks the default member of a type union (e.g. `*\"a\"|*\"b\"`). When the parser finishes the first type atom and the next token is not `|` (no union follows) but a default marker was consumed, it throws notAUnion — a default marker is meaningless outside a union.","triggerScenarios":"Writing a type like `*String` or `*\"x\"` without a `|` union — e.g. a type annotation `x: *String` or an ambiguous `var x: *Foo = ...`.","commonSituations":"Typos where the `|` separating union members was deleted; misunderstanding `*` as a wildcard or pointer; copy-pasting a union default from an example and trimming the union to one member.","solutions":["Remove the `*` marker if the type is not a union.","Add the missing union member(s), e.g. change `*String` to `*\"a\"|\"b\"` or `\"a\"|*\"b\"`.","Check for a swallowed `|` character during editing or copy-paste."],"exampleFix":"// before\nname: *\"apple\"\n\n// after\nname: *\"apple\"|\"orange\"","handlingStrategy":"validation","validationCode":"// A `*` in a type position must be followed by more union members\nfunction defaultMarkerInUnion(typeExpr) {\n  if (!typeExpr.includes('*')) return true;\n  return typeExpr.includes('|');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only use `*` when the type has at least two `|`-separated members.","Remember `*` means 'union default', not wildcard or pointer.","When trimming a union example, remove the `*` from the surviving member."],"tags":["pkl","parser","type-system","union"],"backgroundTag":"invalid-argument-value","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}