apple/pkl · error · VmTypeMismatchException.ClassType
VmTypeMismatchException.ClassType (value is not a subclass…
Error message
VmTypeMismatchException.ClassType (value is not a subclass of the expected class)
What it means
ClassClassTypeNode validates that a `Class` value (a Pkl class object) is a subclass of the class expected by the `Class<T>` type argument. When value.isSubclassOf(clazz) fails, it throws VmTypeMismatchException.ClassType reporting the expected class.
Solutions
- Pass a class object that is T or a subclass of T.
- Widen the type argument to a common superclass (or `Any`) if unrelated classes must be accepted.
- Check the expected class named in the error and verify the hierarchy with `isSubclassOf`.
Example fix
// before elemClass: Class<Animal> = Robot // after (Robot is not an Animal) elemClass: Class<Any> = Robot
Defensive patterns
Strategy: validation
Validate before calling
// Pkl: check subclass relation before passing a class object function checkClass(c: Class): Boolean = c.isSubclassOf(Animal)
Type guard
value is Class && value.isSubclassOf(Animal)
Prevention
- Verify class hierarchies with isSubclassOf before passing class objects.
- Widen Class<T> arguments to a common superclass when multiple hierarchies are involved.
- Keep hierarchy refactors covered by pkl test fixtures.
When it happens
Trigger: A `Class<T>` annotation (e.g. `Class<Animal>`) receives a class object that is not T or a subclass of T (e.g. the class object `Unrelated`), or a sibling class at the same level.
Common situations: Factory/registry patterns that pass class objects around (`elementClass: Class<...>`); changing a class hierarchy so a previously-passing class object no longer derives from T; typos selecting the wrong class.
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
- cannotExportValue
- cannotFlattenCollectionWithNonCollectionElement
- cannotIterateOverThisValue
- cannotSpreadObject
- double
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/7730d6b7ab79ce2d.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java:3282
// safe to init clazz here (instead of on init and typealias instantiate)
// because in the typealias case this node will never execute prior to instantiation
initVmClass();
// Fast path: all classes match Class<Any> / Class<unknown> / Class<type arg>.
// In this case, skip the subclass check and behave like a bare `Class` type annotation.
if (clazz == BaseModule.getAnyClass()) {
return value;
}
// clazz will be null iff the type arg is a not a valid class type
if (clazz == null) {
CompilerDirectives.transferToInterpreter();
throw new VmTypeMismatchException.ClassType(sourceSection, value, typeNode.doExport());
}
if (!value.isSubclassOf(clazz)) {
CompilerDirectives.transferToInterpreter();
throw new VmTypeMismatchException.ClassType(sourceSection, value, clazz);
}
return value;
}
@Fallback
protected Object fallback(Object value) {
throw typeMismatch(value, BaseModule.getClassClass());
}
@Override
protected boolean acceptTypeNode(boolean visitTypeArguments, TypeNodeConsumer consumer) {
if (visitTypeArguments) {
return consumer.accept(this) && typeNode.acceptTypeNode(visitTypeArguments, consumer);
}
return consumer.accept(this);
}
View on GitHub (pinned to f3efcbfc9b)