apple/pkl · error · VmException
notASubclassOfTyped
notASubclassOfTyped
Error message
notASubclassOfTyped
What it means
DynamicNodes' `toTyped` method converts a Dynamic object into an instance of a given Pkl class. The argument must be a class that is a subclass of `Typed` (the base of all typed object classes); otherwise it throws `notASubclassOfTyped`. Classes like Module, List, Map or user classes not extending Typed cannot be used as conversion targets.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/stdlib/base/DynamicNodes.java:101
protected VmList eval(VmDynamic self) {
var builder = VmList.EMPTY.builder();
self.forceAndIterateMemberValues( // could be smarter and only force elements
(key, member, value) -> {
if (member.isElement()) {
builder.add(value);
}
return true;
});
return builder.build();
}
}
public abstract static class toTyped extends ExternalMethod1Node {
@Specialization
protected VmObjectLike eval(VmDynamic self, VmClass clazz) {
if (!clazz.isSubclassOf(BaseModule.getTypedClass())) {
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder().evalError("notASubclassOfTyped", clazz).build();
}
VmUtils.checkIsInstantiable(clazz, this);
var result =
new VmTyped(
VmUtils.createEmptyMaterializedFrame(),
clazz.getPrototype(),
clazz,
clazz.getDynamicToTypedMembers());
result.setExtraStorage(self);
return result;
}
}
}
View on GitHub (pinned to f3efcbfc9b)
Solutions
- Pass a class declared with properties (a typed class) that implicitly subclasses `Typed`, e.g. `dynamic.toTyped(MyConfig)`.
- Verify the argument is a class value (lowercase `Class` reference, not an instance or module).
- If the target is a module, use module-appropriate conversion instead of `toTyped`.
- Check that the class was not refactored into a non-Typed base class.
Example fix
// before typed = dynamic.toTyped(Listing) // Listing is not a subclass of Typed // after typed = dynamic.toTyped(MyConfigClass) // a typed class
Defensive patterns
Strategy: type-guard
Type guard
// Pkl: only call toTyped with typed classes function canToTyped(clazz) = clazz.isSubclassOf(Typed)
Prevention
- Only pass classes that declare typed properties
- Don't pass modules, Listings, or primitive classes to toTyped
- Verify class references after refactors
When it happens
Trigger: Calling `dynamic.toTyped(SomeClass)` (DynamicNodes.java:101) where SomeClass is a Pkl class not derived from `Typed` — e.g. passing `Int`, `Listing`, `Module`, or an annotation/interface-like class.
Common situations: Mixing up class references when converting dynamic config (passing a module class instead of a typed class), refactoring that replaced a typed class with an untyped base, or generic helper code that accepts any `Class` value.
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
- typeMismatch
- type mismatch: value is not of type Typed
- type mismatch: value is not of type Dynamic
- Error converting property `%s` in Pkl object of type `%s` to
- The top-level value of a YAML stream must have type `Collect
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/fd3b7a1753057907.
Report an issue: GitHub.