apple/pkl · error
cannotExtendFinalClass
cannotExtendFinalClass
Error message
cannotExtendFinalClass
What it means
Pkl throws cannotExtendFinalClass when a class declares `extends` on a class marked `closed`/final (isClosed() true) in the non-module branch of checkSupertype. Final classes forbid subclassing to preserve invariants, so the declaration is rejected with the final class's display name. External (standard-library) classes are likewise barred unless the extender is itself a standard-library class.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/member/ClassNode.java:195
.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()) {
throw exceptionBuilder()
.evalError("cannotExtendFinalClass", superclass.getDisplayName())
.withSourceSection(supertypeNode.getSourceSection())
.build();
}
if (superclass.isExternal() && !classInfo.isStandardLibraryClass()) {
throw new VmExceptionBuilder()
.evalError("cannotExtendExternalClass", superclass.getDisplayName())
.withSourceSection(supertypeNode.getSourceSection())
.build();
}
}
}
}
View on GitHub (pinned to f3efcbfc9b)
Solutions
- Remove the extends clause and use composition instead of inheritance.
- Use an object literal (`new`) or amending (`...`) to customize instances rather than subclassing.
- If the class is your own, drop the `closed` modifier to allow extension.
- For stdlib classes, wrap or convert values rather than extending them.
Example fix
// before
class MyString extends String {}
// after
import "pkl:base"
myStr = ("prefix" + someBase) // compose instead of extend Defensive patterns
Strategy: validation
Validate before calling
// Before extending, confirm the superclass is neither closed nor external: // avoid `extends String` / extends any class declared `closed class ...` // pkl eval fails at class definition with cannotExtendFinalClass.
Prevention
- Never extend standard-library classes; wrap or convert values instead.
- Look for `closed` on a class before writing extends.
- Use `new` object literals or amend (`...`) to customize instances.
- Track library upgrades where classes become closed.
When it happens
Trigger: Extending a class declared `closed` in user or library code; extending an external/standard-library class (isExternal) from non-standard-library code; a library release that closed a previously open class.
Common situations: Trying to subclass String/List-like stdlib classes; extending a framework class that was made final for safety; upgrading a dependency whose classes are now closed, breaking previously valid Pkl code.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- classCannotExtendSelf
- Values of type `Class` cannot be rendered as YAML. Value: %s
- cannotExtendExternalClass
- noImplementationForAbstractMethod
- noImplementationForAbstractMethods
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/3dee025ed7b3162a.
Report an issue: GitHub.