{"record":{"id":"1e2f892945d03d14","repo":"apple/pkl","slug":"union-type-mismatch","errorCode":null,"errorMessage":"union type mismatch","messagePattern":"union type mismatch","errorType":"error_code","errorClass":"VmTypeMismatchException.Union","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java","lineNumber":1088,"sourceCode":"      // if enabled, re-execute type checks to generate power assertions\n      localContext.setInTypeTest(wasInTypeTest);\n      if (VmContext.get(this).getPowerAssertionsEnabled()\n          && (!wasInTypeTest || localContext.hasActiveTracker())) {\n        for (var i = 0; i < elementTypeNodes.length; i++) {\n          var elementTypeNode = elementTypeNodes[i];\n          try {\n            if (shouldEagerCheck) {\n              elementTypeNode.executeEagerly(frame, value);\n            } else {\n              elementTypeNode.executeLazily(frame, value);\n            }\n          } catch (VmTypeMismatchException e) {\n            typeMismatches[i] = e;\n          }\n        }\n      }\n\n      throw new VmTypeMismatchException.Union(sourceSection, value, this, typeMismatches);\n    }\n\n    @Override\n    public Object executeEagerly(VirtualFrame frame, Object value) {\n      // escape analysis should remove this allocation in compiled code\n      var typeMismatches = new VmTypeMismatchException[elementTypeNodes.length];\n\n      // disallow power assertions from triggering in case one union member checks successfully\n      var localContext = VmLanguage.get(this).localContext.get();\n      var wasInTypeTest = localContext.isInTypeTest();\n      localContext.setInTypeTest(true);\n\n      for (var i = 0; i < elementTypeNodes.length; i++) {\n        // eager checks\n        try {\n          var result = elementTypeNodes[i].executeEagerly(frame, value);\n          localContext.setInTypeTest(wasInTypeTest);\n          return result;","sourceCodeStart":1070,"sourceCodeEnd":1106,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java#L1070-L1106","documentation":"Pkl's UnionTypeNode checks a value against each member of a union type (e.g. `Int|String|Listing<Float>`). It tries every member, collecting each member's VmTypeMismatchException; if none succeeds, it throws VmTypeMismatchException.Union summarizing why every union member rejected the value. This is Pkl's standard 'value matches none of the union alternatives' type-check failure.","triggerScenarios":"A property/type-alias/type-argument annotated with a union type receives a value that fails every member's type check, e.g. a property `x: Int|String` assigned `true`, or `Listing<Int>|Listing<String>` given elements of neither element type. Raised lazily (executeLazily) or eagerly depending on member types.","commonSituations":"Config values coming from external sources (CLI flags, environment substitution, rendered/amend values) whose inferred Pkl value is not one of the declared union alternatives; typos in string-literal unions; widening a property's union type without updating all importing modules.","solutions":["Fix the value so it matches one of the union's members (check the per-member messages in the error output).","Widen the union type in the schema to include the value's actual type (e.g. add `Null` if the value can be absent).","If the value comes from an external source, coerce or validate it before feeding it to the module.","Check for typos in string-literal union members."],"exampleFix":"// before\nname: \"dev\" | \"prod\" | \"staging\"\n// config sets name = \"Prod\"\n// after\nname: \"dev\" | \"prod\" | \"staging\"\n// config sets name = \"prod\"","handlingStrategy":"validation","validationCode":"// Pkl: guard before assigning to a union-typed property\nfunction checkName(v: String): String =\n  if (v == \"dev\" || v == \"prod\" || v == \"staging\") v\n  else throw(\"name must be one of dev|prod|staging, got: \\(v)\")","typeGuard":"// Pkl type test\nx is Int | String","tryCatchPattern":null,"preventionTips":["Test modules with `pkl test` covering each union member and a negative case.","Avoid overly wide unions; validate external input at the module boundary.","Read the per-member sub-errors in the message to find the nearest match."],"tags":["pkl","type-mismatch","union-type"],"backgroundTag":"type-mismatch","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}