apple/pkl · error
moduleCannotExtendSelf
moduleCannotExtendSelf
Error message
moduleCannotExtendSelf
What it means
Pkl throws moduleCannotExtendSelf when a module declares itself as its own superclass (e.g. `extends` naming the enclosing module). ClassNode.checkSupertype compares the resolved superclass with the cached class of the module being defined and rejects direct self-extension. A module extending itself would create a cyclic inheritance chain, so it is stopped at class-definition time.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/member/ClassNode.java:176
cachedClass.onOwnClassInitialized();
localContext.endClassInit();
return cachedClass;
} catch (Throwable e) {
localContext.clearClassInitState();
throw e;
}
}
private void checkSupertype(TypeNode supertypeNode, @Nullable VmClass superclass) {
if (superclass == null) {
throw exceptionBuilder()
.evalError("invalidSupertype", supertypeNode.getSourceSection().getCharacters())
.withSourceSection(supertypeNode.getSourceSection())
.build();
}
if (moduleInfo != null) {
if (cachedClass == superclass) {
throw exceptionBuilder()
.evalError("moduleCannotExtendSelf", moduleInfo.getModuleName())
.withSourceSection(supertypeNode.getSourceSection())
.build();
}
if (superclass.isClosed()) {
throw exceptionBuilder()
.evalError("cannotExtendFinalModule", superclass.getModuleName())
.withSourceSection(supertypeNode.getSourceSection())
.build();
}
} else {
if (cachedClass == superclass) {
throw exceptionBuilder()
.evalError("classCannotExtendSelf", superclass.getDisplayName())
.withSourceSection(supertypeNode.getSourceSection())
.build();
}
if (superclass.isClosed()) {View on GitHub (pinned to f3efcbfc9b)
Solutions
- Remove the `extends` clause that names the module itself.
- If you intended inheritance from a base config, extend a different module that does not (transitively) extend this one.
- Break any import cycle so the module does not reach itself through re-exports.
- Rename the target if you actually meant a different module with a similar name.
Example fix
// before (inside base.pkl) module base extends base // module extends itself // after module base
Defensive patterns
Strategy: validation
Validate before calling
// Check the extends chain of a module before shipping: // pkl eval base.pkl -> moduleCannotExtendSelf surfaces at load // Audit imports: a module must never import itself (directly or via a barrel module).
Prevention
- Never write an extends clause naming the enclosing module.
- Keep the module hierarchy acyclic; draw the base->derived graph when it grows.
- Avoid barrel/index modules that re-import themselves transitively.
- Run pkl eval in CI to catch cycles at definition time.
When it happens
Trigger: Writing `extends <thisModuleName>` inside the module itself; a module importing itself (directly or via a re-export) and extending that import; circular module extends where the chain loops back to the same module.
Common situations: Copy-pasting an `extends` clause into the base module itself; refactoring a two-module hierarchy into one file and forgetting to drop the extends; accidentally importing a module into itself through a barrel/index module.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- cannotExtendFinalModule
- cannotExtendExternalClass
- noImplementationForAbstractMethod
- noImplementationForAbstractMethods
- externalClass
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/8af3629e51f3b708.
Report an issue: GitHub.