apple/pkl · error · VmTypeMismatchException.ClassType
VmTypeMismatchException.ClassType (type argument is not a va
Error message
VmTypeMismatchException.ClassType (type argument is not a valid class type)
What it means
ClassClassTypeNode checks values typed as `Class<T>` (a Pkl class object). After resolving the expected class from the type argument, if the resolved class is null — meaning the type argument is not a valid, concrete class type (e.g. a typealias to a non-class, union, or unknown/parametric type that could not be reduced) — it throws VmTypeMismatchException.ClassType with the exported type argument.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java:3277
return BaseModule.getClassClass();
}
@Specialization
protected Object eval(VmClass value) {
// 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) {View on GitHub (pinned to f3efcbfc9b)
Solutions
- Use a concrete class as the type argument (e.g. `Class<Foo>`, or `Class<Any>` for any class).
- If using a typealias, make it alias a single class type.
- Handle parametric/type-variable arguments by declaring them as `Class<unknown>`-compatible or resolving them at instantiation.
Example fix
// before alias FooOrBar = Foo | Bar k: Class<FooOrBar> = Foo // after k: Class<Foo> = Foo
Defensive patterns
Strategy: type-guard
Validate before calling
// Pkl: only concrete classes are valid Class<T> arguments k: Class<Foo> = Foo // not Class<SomeUnion> or an unresolved type variable
Type guard
value is Class
Prevention
- Never parameterize Class<...> with unions or non-class typealiases.
- Use Class<Any> when any class must be accepted.
- Resolve type variables before instantiating generic Class<T> annotations.
When it happens
Trigger: A `Class<...>` type annotation whose type argument is not a valid class type: the argument is a union, a typealias that does not reduce to a class, or a type variable that cannot be resolved; then a VmClass value is checked against it.
Common situations: Passing `Class<SomeUnion>` or `Class<SomeTypeAlias>` where the alias/union doesn't denote a single class; generic code taking `Class<T>` with an unresolved T; refactoring a typealias that previously aliased a class into a constrained/union type.
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
- Error converting property `%s` in Pkl object of type `%s` to
- The top-level value of a YAML stream must have type `Collect
- type constraint mismatch
- type mismatch
- type mismatch (Nothing type)
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/8e0f3144d5f22049.
Report an issue: GitHub.