apple/pkl · error · VmException
missingLocalPropertyValue
missingLocalPropertyValue
Error message
missingLocalPropertyValue
What it means
A `local` property must have a value — locals exist only within the enclosing scope and cannot be external or deferred. When a local property has no body/expression, AstBuilder calls missingLocalPropertyValue(typeAnnotation) (asserting a type annotation exists), producing an error anchored to the type annotation.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:2093
bodyNode = visitExpr(expr);
} else if (!objectBodies.isEmpty()) { // prop { ... }
if (typeAnnotation != null) {
throw exceptionBuilder()
.evalError("cannotAmendPropertyDefinition")
.withSourceSection(createSourceSection(entry))
.build();
}
bodyNode =
doVisitObjectBody(
objectBodies,
new ReadSuperPropertyNode(
unavailableSourceSection(),
scope.getName(),
scope.getConstLevel() == ConstLevel.ALL));
} else { // no value given
if (isLocal) {
assert typeAnnotation != null;
throw missingLocalPropertyValue(typeAnnotation);
}
if (VmModifier.isExternal(modifiers)) {
bodyNode =
externalMemberRegistry.getPropertyBody(scope.getQualifiedName(), headerSection);
if (bodyNode instanceof LanguageAwareNode languageAwareNode) {
languageAwareNode.initLanguage(language);
}
} else {
bodyNode = null; // will be given a default by UnresolvedPropertyNode
}
}
var typeAnnNode = visitTypeAnnotation(typeAnnotation);
return new UnresolvedPropertyNode(
language,
sourceSection,
headerSection,View on GitHub (pinned to f3efcbfc9b)
Solutions
- Add a value: `local prop: Type = expr`.
- Remove the `local` modifier if it should be an external or overridable module property.
- Remove the declaration entirely if unused.
Example fix
// before local timeout: Duration // after local timeout: Duration = 30.s
Defensive patterns
Strategy: validation
Validate before calling
// Every local declaration must have an initializer:
if (isLocalDecl(decl) && decl.getInitializer() == null) {
report(decl, "local properties require a value");
} Prevention
- Never leave `local` declarations without `= expr`.
- If you need a placeholder that is filled later, use a normal (non-local) property with a default.
- Review refactors that change module properties into locals.
When it happens
Trigger: Declaring `local prop: Type` (or `local const prop: Type`) with no `= expr` and no object body — isLocal is true and the no-value branch is taken.
Common situations: Declaring a local constant/placeholder intending to fill it in later; converting a module property (which may be external) to a local without adding a value.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- externalMemberCannotHaveBody
- ${errorMessage} This will be an error in a future release.
- duplicateDefinition
- classMustBeLocal
- typeAliasMustBeLocal
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/c464e6f895918c15.
Report an issue: GitHub.