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

  1. Add a value: `local prop: Type = expr`.
  2. Remove the `local` modifier if it should be an external or overridable module property.
  3. 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

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


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/c464e6f895918c15. Report an issue: GitHub.