apple/pkl · error · VmTypeMismatchException.Union

VmTypeMismatchException.Union (type mismatch for union type)

Error message

VmTypeMismatchException.Union (type mismatch for union type)

What it means

Same family as error 80 but thrown from UnionTypeNode.executeEagerly: when a union type's members must be checked eagerly (shallow-forced), Pkl runs each member check and, if all fail, throws VmTypeMismatchException.Union with the collected per-member failures. Eager checking is used when members require it (e.g. two Listing/Mapping members) so lazily-hidden errors cannot escape.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java:1126

          typeMismatches[i] = e;
        }
      }

      // all members failed to type check
      // if enabled, re-execute type checks to generate power assertions
      localContext.setInTypeTest(wasInTypeTest);
      if (VmContext.get(this).getPowerAssertionsEnabled()
          && (!wasInTypeTest || localContext.hasActiveTracker())) {
        for (var i = 0; i < elementTypeNodes.length; i++) {
          try {
            elementTypeNodes[i].executeEagerly(frame, value);
          } catch (VmTypeMismatchException e) {
            typeMismatches[i] = e;
          }
        }
      }

      throw new VmTypeMismatchException.Union(sourceSection, value, this, typeMismatches);
    }
  }

  public static final class UnionOfStringLiteralsTypeNode extends ObjectSlotTypeNode {
    private final Set<String> stringLiterals;
    private final @Nullable String unionDefault;

    UnionOfStringLiteralsTypeNode(
        SourceSection sourceSection, int defaultIndex, Set<String> stringLiterals) {
      super(sourceSection);

      assert !stringLiterals.isEmpty();
      this.stringLiterals = stringLiterals;
      if (defaultIndex == -1) {
        unionDefault = null;
      } else {
        unionDefault = stringLiterals.toArray(new String[0])[defaultIndex];
      }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Fix the collection's element types to match one union member.
  2. Adjust the union annotation to cover the actual element types.
  3. Read the per-member sub-exceptions to identify which member came closest and why it rejected the value.

Example fix

// before
items: Listing<Int> | Listing<String>  // items contains [1.5]
// after
items: Listing<Int> | Listing<String> | Listing<Float>
Defensive patterns

Strategy: validation

Validate before calling

// Pkl: verify listing elements eagerly
function checkInts(l: Listing): Listing<Int> =
  l.getOrElse(0) is Int ? l as Listing<Int> : throw("listing elements must be Int")

Type guard

value is Listing<Int> | Listing<String>

Prevention

When it happens

Trigger: A union type annotation like `Listing<Int>|Listing<String>` is checked eagerly against a value that matches no member; each member's executeEagerly throws and the aggregated VmTypeMismatchException.Union is raised.

Common situations: Collections whose elements don't match any listing/mapping alternative in the union; amending or importing modules where a collection property's union annotation no longer matches the produced data.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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