apple/pkl · error

moduleMethodMustBeLocal

moduleMethodMustBeLocal

Error message

moduleMethodMustBeLocal / objectMethodMustBeLocal

What it means

Pkl requires object member methods (declared with `::` between name and parens, e.g. `foo() = ...`) to be declared `local`. When a method on a module or object lacks the `local` modifier, AstBuilder throws `moduleMethodMustBeLocal` (for module-level methods) or `objectMethodMustBeLocal` (for object members). Methods are not externally visible members in Pkl; only locals are allowed.

Source

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

        isModuleMethod);
  }

  private ObjectMember doVisitObjectMethod(
      Node method,
      List<Modifier> modifierNodes,
      Span headerSpan,
      Identifier identifier,
      ParameterList paramList,
      @Nullable TypeParameterList typeParamList,
      Expr expr,
      @Nullable TypeAnnotation typeAnnotation,
      boolean isModuleMethod) {
    var modifiers =
        doVisitModifiers(
            modifierNodes, VmModifier.VALID_OBJECT_MEMBER_MODIFIERS, "invalidObjectMemberModifier");

    if (!VmModifier.isLocal(modifiers)) {
      throw exceptionBuilder()
          .evalError(isModuleMethod ? "moduleMethodMustBeLocal" : "objectMethodMustBeLocal")
          .withSourceSection(createSourceSection(headerSpan))
          .build();
    }

    var methodName = org.pkl.core.runtime.Identifier.method(identifier.getValue(), true);

    var frameDescriptorBuilderAndBindings = createFrameDescriptorBuilderAndSlotVariables(paramList);

    var frameDescriptorBuilder = frameDescriptorBuilderAndBindings.first;
    var bindings = frameDescriptorBuilderAndBindings.second;

    return symbolTable.enterMethod(
        methodName,
        getConstLevel(modifiers),
        bindings,
        frameDescriptorBuilder,
        List.of(),

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Add the `local` modifier: `local function compute() = ...`.
  2. If the member should be a property rather than a method, rewrite it as `foo = ...`.
  3. Check that every `...(...) = ...` method declaration in the module/object carries `local`.

Example fix

// before
function double(n) = n * 2
// after
local function double(n) = n * 2
Defensive patterns

Strategy: validation

Validate before calling

// every Pkl method declaration must start with `local`
if (/^[ \t]*(?!local\b)[a-zA-Z_]\w*\s*\([^)]*\)\s*=/.test(pklSource)) {
  throw new Error("object/module methods must be declared `local`");
}

Prevention

When it happens

Trigger: Writing `function compute() = ...` (no `local`) inside an object body or at module level in AstBuilder's method-member visitation (AstBuilder.java:2809).

Common situations: Developers coming from Kotlin/Java writing plain `foo() = ...` in a Pkl module; forgetting the `local` keyword when declaring helper functions; migrating code where the modifier was dropped.

Understand the failure class

Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.

Related errors


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