apple/pkl · error · VmException
abstractMemberCannotHaveBody
abstractMemberCannotHaveBody
Error message
abstractMemberCannotHaveBody
What it means
Pkl throws this at build time (AstBuilder) when a class or object member is declared `abstract` but also has a body. Abstract members are placeholders that subclasses must implement; they cannot carry an implementation. The parser-built AST rejects this combination while visiting the member's header/body.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:2163
var annotations = doVisitAnnotations(entry.getAnnotations(), methodName);
return symbolTable.enterMethod(
methodName,
getConstLevel(modifiers),
bindings,
descriptorBuilder,
typeParameters,
scope -> {
ExpressionNode bodyNode;
if (bodyContext != null) {
if (VmModifier.isExternal(modifiers)) {
throw exceptionBuilder()
.evalError("externalMemberCannotHaveBody")
.withSourceSection(headerSection)
.build();
}
if (VmModifier.isAbstract(modifiers)) {
throw exceptionBuilder()
.evalError("abstractMemberCannotHaveBody")
.withSourceSection(headerSection)
.build();
}
bodyNode = visitExpr(bodyContext);
} else {
if (VmModifier.isExternal(modifiers)) {
bodyNode =
externalMemberRegistry.getFunctionBody(
scope.getQualifiedName(), headerSection, paramCount);
if (bodyNode instanceof LanguageAwareNode languageAwareNode) {
languageAwareNode.initLanguage(language);
}
} else if (VmModifier.isAbstract(modifiers)) {
bodyNode =
new CannotInvokeAbstractFunctionNode(headerSection, scope.getQualifiedName());
} else {
throw exceptionBuilder()View on GitHub (pinned to f3efcbfc9b)
Solutions
- Remove the `= body` / method body so the member is a pure abstract declaration.
- Or remove the `abstract` modifier if the member should keep its implementation.
- If the intent was a default that subclasses override, declare it normally (no modifier) instead of abstract.
Example fix
// before abstract function endpoint(): String = "https://api.example.com" // after abstract function endpoint(): String
Defensive patterns
Strategy: validation
Validate before calling
// before compiling, scan member declarations
function hasAbstractWithBody(member) {
return member.modifiers.includes('abstract') && member.body != null;
}
if (members.some(hasAbstractWithBody)) throw new Error('abstract member must not have a body'); Prevention
- Treat `abstract` as a signature-only declaration — never write `=` after it.
- Review diffs that add the `abstract` modifier for leftover bodies.
- Use pkl format/lint tooling in CI to catch this before evaluation.
When it happens
Trigger: Declaring a member inside a class (Amends/ClassBody) with both the `abstract` modifier and a non-empty body, e.g. `abstract function foo(): Int = 1` or `abstract x: String = "a"`. The check fires in the branch where the body exists and `VmModifier.isAbstract(modifiers)` is true.
Common situations: Converting a concrete member to abstract (adding `abstract`) without deleting its body; copy-pasting a member and adding `abstract` to satisfy an overridden contract; misunderstanding Pkl's abstract semantics compared to Java interfaces.
Related errors
- missingMethodBody
- cannotDeclareTypeParameter
- duplicateTypeParameter
- invalidTypeName
- invalidConstObjectMemberModifier
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/c3f7d8c1215bc1ae.
Report an issue: GitHub.