apple/pkl · error · VmException

externalMemberCannotHaveBody

externalMemberCannotHaveBody

Error message

externalMemberCannotHaveBody

What it means

A property marked `external` declares its implementation is provided by the host (via externalMemberRegistry) and must not have an inline body. AstBuilder throws externalMemberCannotHaveBody when an external property definition also has `prop = expr`, pointing at the header section.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:2070

    var fullModifiers =
        doVisitModifiers(
            modifierList, VmModifier.VALID_PROPERTY_MODIFIERS, "invalidPropertyModifier");
    // for compat, properties may be abstract, but ignore this
    var modifiers = fullModifiers & ~VmModifier.ABSTRACT;

    var isLocal = VmModifier.isLocal(modifiers);
    var propertyName = org.pkl.core.runtime.Identifier.property(name.getValue(), isLocal);
    var annotationNodes = doVisitAnnotations(annotations, propertyName);

    return symbolTable.enterProperty(
        propertyName,
        getConstLevel(modifiers),
        scope -> {
          ExpressionNode bodyNode;

          if (expr != null) { // prop = expr
            if (VmModifier.isExternal(modifiers)) {
              throw exceptionBuilder()
                  .evalError("externalMemberCannotHaveBody")
                  .withSourceSection(headerSection)
                  .build();
            }
            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(),

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Remove the `external` modifier and keep the body.
  2. Remove the `= expr` body and keep `external`, registering the implementation in the ExternalMemberRegistry.
  3. Check whether you meant `abstract` (body-less, subclass provides) rather than `external`.

Example fix

// before
external prop: Int = 42

// after
prop: Int = 42
Defensive patterns

Strategy: validation

Validate before calling

// Ensure external properties have no inline body:
if (hasModifier(prop, "external") && prop.hasValueExpression()) {
  report(prop, "external properties cannot have a body");
}

Prevention

When it happens

Trigger: Writing `external prop: Type = expr` — i.e. VmModifier.isExternal(modifiers) is true while an expr body is present — during property AST construction.

Common situations: Defining properties that mirror built-in external members of pkl.base modules; hand-writing module code that mimics stdlib declarations; migrating a property from normal to external while leaving its body.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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