apple/pkl · error · VmTypeMismatchException.Reference
VmTypeMismatchException.Reference (referent type is not a…
Error message
VmTypeMismatchException.Reference (referent type is not a subtype)
What it means
In ReferenceTypeNode.doEval, after the domain check passes, Pkl verifies the reference's referent type via value.referentTypeIsSubtypeOf(...). If the referent type is not a subtype of the declared referent type, it throws VmTypeMismatchException.Reference indicating the reference points at a value of an incompatible type.
Solutions
- Make the referenced value an instance of (a subtype of) the declared referent type.
- Widen the declared referent type parameter to a common supertype of the actual referents.
- Check the exported referent type in the message to see exactly which type was expected.
Example fix
// before base: Reference<Base> = derived // derived: Derived, not a subtype of Base // after abstract class Base class Derived extends Base base: Reference<Base> = derived
Defensive patterns
Strategy: type-guard
Validate before calling
// Pkl: verify referent type before assigning function checkReferent(r: Reference): Boolean = r.referent is ExpectedType
Type guard
value is Reference<ExpectedType>
Prevention
- Ensure referenced objects derive from the declared referent class.
- When narrowing a referent type, update all producers of the reference.
- Use `is` type tests on the referent before constructing the reference.
When it happens
Trigger: A `Reference<T>` (or TypeAlias/constrained reference) is checked where the actual referent's class is not a subtype of T; doEval compares referentTypeNode.doExport() against the value's referent type using thisClass/moduleClass context and throws on failure.
Common situations: Storing a reference to an object of the wrong class; changing a property's declared referent type to a narrower class while existing references still point at the broader type; typealias constraints over references after upstream type changes.
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
- VmTypeMismatchException.Reference (domain type check failed…
- cannotExportValue
- cannotFlattenCollectionWithNonCollectionElement
- cannotIterateOverThisValue
- cannotSpreadObject
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/e1acb762430b89e6.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java:2251
// 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();
if (value.referentTypeIsSubtypeOf(referentType, thisClass.export(), moduleClass.export())) {
return value;
}
throw new VmTypeMismatchException.Reference(
sourceSection, value, domainTypeNode.doExport(), referentType);
}
@Fallback
protected Object fallback(Object value) {
throw typeMismatch(value, RefModule.getReferenceClass());
}
@Override
protected boolean acceptTypeNode(boolean visitTypeArguments, TypeNodeConsumer consumer) {
if (visitTypeArguments)
return consumer.accept(this)
&& consumer.accept(domainTypeNode)
&& consumer.accept(referentTypeNode);
return consumer.accept(this);
}
@OverrideView on GitHub (pinned to f3efcbfc9b)