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
- Add the `local` modifier: `local function compute() = ...`.
- If the member should be a property rather than a method, rewrite it as `foo = ...`.
- 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
- Habit: write `local function name(...) = ...` for every helper method.
- Let `pkl format` + `pkl eval` lint the module in CI.
- Remember Pkl has no public object methods — only `local` ones.
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
- invalidObjectMemberModifier
- redundantHiddenModifier
- redundantFixedModifier
- redundantOpenModifier
- Cannot parse `%s` as number.
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/aaf2d3735779956c.
Report an issue: GitHub.