apple/pkl · error
notAModuleType
notAModuleType
Error message
notAModuleType
What it means
Raised by `UnresolvedTypeNode.Module#execute`: a type annotation references a module (an object known to be a module), but that module object is not a prototype, so it cannot be used as a type. The error message `notAModuleType` includes the module name. Pkl requires type positions to reference module prototypes (the module itself), not instances/amendments of it.
Solutions
- Use the plain module import in type position: `import "myModule.pkl"` then `x: myModule`.
- Do not amend or instantiate the module object that you reference as a type; keep a separate import for type use.
- If dynamic `import()` is needed, ensure the resolved value is the untouched module prototype.
- Check the module name in the error message and verify the referenced identifier is the module itself.
Example fix
// before
import "config.pkl"
mod = (config) { x = 1 }
y: mod = ... // mod is amended, not a prototype
// after
import "config.pkl"
y: config = ... Defensive patterns
Strategy: type-guard
Validate before calling
function expectModulePrototype(mod) {
if (!mod || mod.__amended) throw new Error("type annotations must reference the module prototype, not an amendment");
} Type guard
function isModulePrototype(v) { return v != null && typeof v === "object" && v.__isModule === true && !v.__amended; } Try / catch
try {
useAsType(mod);
} catch (e) {
// re-import the module prototype and retry
} Prevention
- Use plain `import` statements for values used in type position.
- Never amend a module object you also reference as a type.
- Keep separate identifiers for module-as-type vs module-as-value.
When it happens
Trigger: Writing a type annotation that resolves to a non-prototype module object, e.g. `x: someModule` where `someModule` was obtained by amending or instantiating rather than importing, or using `import()` result stored in a variable that got amended.
Common situations: Amending a module in a variable and then using the variable in type position; `import("...")` assigned and mutated before use as a type; typos that resolve to a submodule instance instead of the module class.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- cannotExtendFinalModule
- cannotHaveRelativeResource
- expectedModuleAsArgument
- expectedModuleAsReceiver
- externalClass
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/423df97d5b953bca.
Report an issue: GitHub.
Appendix: source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/type/UnresolvedTypeNode.java:218
case "UInt16":
return new UIntTypeAliasTypeNode(alias, 0x000000000000FFFFL);
case "Int32":
return new Int32TypeAliasTypeNode();
case "UInt32":
return new UIntTypeAliasTypeNode(alias, 0x00000000FFFFFFFFL);
case "UInt":
return new UIntTypeAliasTypeNode(alias, 0x7FFFFFFFFFFFFFFFL);
}
}
return new TypeAliasTypeNode(sourceSection, alias, new TypeNode[0]);
}
var module = (VmTyped) type;
assert module.isModuleObject();
var clazz = module.getVmClass();
if (!module.isPrototype()) {
throw exceptionBuilder().evalError("notAModuleType", clazz.getModuleName()).build();
}
return TypeNode.forClass(sourceSection, module.getVmClass());
}
}
public static final class Parameterized extends UnresolvedTypeNode {
private final VmLanguage language;
@Child private ExpressionNode resolveTypeNode;
@Children private final UnresolvedTypeNode[] typeArgumentNodes;
public Parameterized(
SourceSection sourceSection,
VmLanguage language,
ExpressionNode resolveTypeNode,
UnresolvedTypeNode[] typeArgumentNodes) {
super(sourceSection);
this.language = language;
this.resolveTypeNode = resolveTypeNode;View on GitHub (pinned to f3efcbfc9b)