apple/pkl · error · VmTypeMismatchException.Reference

VmTypeMismatchException.Reference (domain type check failed…

Error message

VmTypeMismatchException.Reference (domain type check failed for reference)

What it means

When checking a `Reference<X>` (a Pkl Reference value), the node first validates the reference's domain by executing its domainTypeNode. If the domain check throws VmTypeMismatchException, the error is re-thrown as VmTypeMismatchException.Reference reporting that the reference's domain is incompatible with the expected domain/referent type.

Solutions

  1. Inspect the reported domain type and make the referenced value's domain conform to it.
  2. Update the Reference<...> type annotation to match the actual domain/referent of the value.
  3. Verify the referenced module/import still exports the expected type after refactoring.

Example fix

// before
ref: Reference<Module_A.Thing> = moduleB.thing
// after
ref: Reference<Module_B.Thing> = moduleB.thing
Defensive patterns

Strategy: type-guard

Validate before calling

// Pkl: check reference domain before use
function checkRef(r: Reference, domain: Class): Boolean = r.domain.getClass().isSubclassOf(domain)

Type guard

value is Reference<ExpectedType>

Prevention

When it happens

Trigger: A value typed as `Reference<T>` (e.g. from pkl:base Reference or Resource/Module references) has a domain that fails its declared domain type check; the catch block at TypeNode.java:2228 converts it into VmTypeMismatchException.Reference with the exported domain and referent types.

Common situations: Working with cross-module or resource references where the referenced object's module/type does not conform to the declared reference type; refactoring module hierarchies so a previously valid reference no longer satisfies its domain constraint.

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/8e8a5dcdd824b0d4. Report an issue: GitHub.

Appendix: source

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

      return violation.getOrNull();
    }

    @Override
    protected final boolean isIncludedInTrace(Node node) {
      return node instanceof ReferenceTypeNode || node instanceof ConstrainedTypeNode;
    }

    @Specialization
    protected Object eval(VirtualFrame frame, VmReference value) {
      if (domainTypeNode.isNoopTypeCheck() && referentTypeNode.isNoopTypeCheck()) {
        return value;
      }

      try {
        domainTypeNode.execute(frame, value.getDomain());
      } catch (VmTypeMismatchException e) {
        CompilerDirectives.transferToInterpreter();
        throw new VmTypeMismatchException.Reference(
            sourceSection, value, domainTypeNode.doExport(), referentTypeNode.doExport());
      }

      // NB: this is correct because the `this` type is not allowed in typealias bodies.
      // So `this` can only correspond to the receiver where the type check/annotation is written.
      var thisClass = ((VmClass) getReceiverClassNode.executeGeneric(frame));

      // NB: This will be wrong for deprecated usage of the `module` type in typealias bodies.
      // It will always resolve to the module where the type check/annotation is written
      // not the type itself. This is no _more_ broken than it was before.
      var moduleClass = VmUtils.getClass(getModuleNode.executeGeneric(frame));

      return doEval(value, thisClass, moduleClass);
    }

    @TruffleBoundary
    private Object doEval(VmReference value, VmClass thisClass, VmClass moduleClass) {
      var referentType = referentTypeNode.doExport();

View on GitHub (pinned to f3efcbfc9b)