{"record":{"id":"aaf2d3735779956c","repo":"apple/pkl","slug":"modulemethodmustbelocal","errorCode":"moduleMethodMustBeLocal","errorMessage":"moduleMethodMustBeLocal / objectMethodMustBeLocal","messagePattern":"moduleMethodMustBeLocal / objectMethodMustBeLocal","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java","lineNumber":2809,"sourceCode":"        isModuleMethod);\n  }\n\n  private ObjectMember doVisitObjectMethod(\n      Node method,\n      List<Modifier> modifierNodes,\n      Span headerSpan,\n      Identifier identifier,\n      ParameterList paramList,\n      @Nullable TypeParameterList typeParamList,\n      Expr expr,\n      @Nullable TypeAnnotation typeAnnotation,\n      boolean isModuleMethod) {\n    var modifiers =\n        doVisitModifiers(\n            modifierNodes, VmModifier.VALID_OBJECT_MEMBER_MODIFIERS, \"invalidObjectMemberModifier\");\n\n    if (!VmModifier.isLocal(modifiers)) {\n      throw exceptionBuilder()\n          .evalError(isModuleMethod ? \"moduleMethodMustBeLocal\" : \"objectMethodMustBeLocal\")\n          .withSourceSection(createSourceSection(headerSpan))\n          .build();\n    }\n\n    var methodName = org.pkl.core.runtime.Identifier.method(identifier.getValue(), true);\n\n    var frameDescriptorBuilderAndBindings = createFrameDescriptorBuilderAndSlotVariables(paramList);\n\n    var frameDescriptorBuilder = frameDescriptorBuilderAndBindings.first;\n    var bindings = frameDescriptorBuilderAndBindings.second;\n\n    return symbolTable.enterMethod(\n        methodName,\n        getConstLevel(modifiers),\n        bindings,\n        frameDescriptorBuilder,\n        List.of(),","sourceCodeStart":2791,"sourceCodeEnd":2827,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java#L2791-L2827","documentation":"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.","triggerScenarios":"Writing `function compute() = ...` (no `local`) inside an object body or at module level in AstBuilder's method-member visitation (AstBuilder.java:2809).","commonSituations":"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.","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`."],"exampleFix":"// before\nfunction double(n) = n * 2\n// after\nlocal function double(n) = n * 2","handlingStrategy":"validation","validationCode":"// every Pkl method declaration must start with `local`\nif (/^[ \\t]*(?!local\\b)[a-zA-Z_]\\w*\\s*\\([^)]*\\)\\s*=/.test(pklSource)) {\n  throw new Error(\"object/module methods must be declared `local`\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["pkl","parser","method-declaration","modifier"],"backgroundTag":"missing-required-flag","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}