{"record":{"id":"8e0f3144d5f22049","repo":"apple/pkl","slug":"vmtypemismatchexception-classtype-type-argument-i","errorCode":null,"errorMessage":"VmTypeMismatchException.ClassType (type argument is not a valid class type)","messagePattern":"VmTypeMismatchException\\.ClassType \\(type argument is not a valid class type\\)","errorType":"exception","errorClass":"VmTypeMismatchException.ClassType","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java","lineNumber":3277,"sourceCode":"      return BaseModule.getClassClass();\n    }\n\n    @Specialization\n    protected Object eval(VmClass value) {\n      // safe to init clazz here (instead of on init and typealias instantiate)\n      // because in the typealias case this node will never execute prior to instantiation\n      initVmClass();\n\n      // Fast path: all classes match Class<Any> / Class<unknown> / Class<type arg>.\n      // In this case, skip the subclass check and behave like a bare `Class` type annotation.\n      if (clazz == BaseModule.getAnyClass()) {\n        return value;\n      }\n\n      // clazz will be null iff the type arg is a not a valid class type\n      if (clazz == null) {\n        CompilerDirectives.transferToInterpreter();\n        throw new VmTypeMismatchException.ClassType(sourceSection, value, typeNode.doExport());\n      }\n\n      if (!value.isSubclassOf(clazz)) {\n        CompilerDirectives.transferToInterpreter();\n        throw new VmTypeMismatchException.ClassType(sourceSection, value, clazz);\n      }\n\n      return value;\n    }\n\n    @Fallback\n    protected Object fallback(Object value) {\n      throw typeMismatch(value, BaseModule.getClassClass());\n    }\n\n    @Override\n    protected boolean acceptTypeNode(boolean visitTypeArguments, TypeNodeConsumer consumer) {\n      if (visitTypeArguments) {","sourceCodeStart":3259,"sourceCodeEnd":3295,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/ast/type/TypeNode.java#L3259-L3295","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nalias FooOrBar = Foo | Bar\nk: Class<FooOrBar> = Foo\n// after\nk: Class<Foo> = Foo","handlingStrategy":"type-guard","validationCode":"// Pkl: only concrete classes are valid Class<T> arguments\nk: Class<Foo> = Foo  // not Class<SomeUnion> or an unresolved type variable","typeGuard":"value is Class","tryCatchPattern":null,"preventionTips":["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."],"tags":["pkl","type-mismatch","class-type"],"backgroundTag":"type-mismatch","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}