apple/pkl · error

cannotAmendLocalPropertyDefinition

cannotAmendLocalPropertyDefinition

Error message

cannotAmendLocalPropertyDefinition

What it means

Pkl throws `cannotAmendLocalPropertyDefinition` when an object body (`{ ... }`) follows a local property definition. Local properties are per-object bindings that cannot be amended by an object body; only regular (non-local) properties support amendment. AstBuilder detects `isLocal` combined with a non-empty body and fails at build time.

Solutions

  1. Remove the `{ ... }` object body from the local property declaration.
  2. If amendment is needed, drop the `local` modifier and use a regular (possibly `hidden`) property.
  3. Assign the extra content as additional local properties instead of amending one local.

Example fix

// before
local base = 1 {
  extra = 2
}
// after
local base = 1
local extra = 2
// or: base = 1 { extra = 2 } without `local`
Defensive patterns

Strategy: validation

Validate before calling

// pkl test / pkl eval catches this at parse time
// grep check: local property followed by '{'
if (/local\s+[a-zA-Z_]\w*\s*=(\s|\S)*\{/.test(pklSource)) {
  throw new Error("local property must not have an amend body");
}

Prevention

When it happens

Trigger: Declaring `local foo = 1 { ... }` or `local foo { ... }` inside an object/class body — i.e. a local modifier plus an object-body block in AstBuilder's object member visitation (file pkl-core/src/main/java/org/pkl/core/ast/builder/AstBuilder.java:2689).

Common situations: Developers converting a regular property to `local` to hide it from output but forgetting it had an amend body; copy-pasting object bodies onto local helper bindings; refactoring amending properties into locals.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

        scope -> {
          if (isLocal) {
            if (expr == null
                && typeAnn != null) { // module property that has type annotation but no value
              throw missingLocalPropertyValue(typeAnn);
            }
          } else {
            if (typeAnn != null) {
              throw exceptionBuilder()
                  .evalError("nonLocalObjectPropertyCannotHaveTypeAnnotation")
                  .withSourceSection(createSourceSection(typeAnn.getType()))
                  .build();
            }
          }

          ExpressionNode bodyNode;
          if (body != null && !body.isEmpty()) { // foo { ... }
            if (isLocal) {
              throw exceptionBuilder()
                  .evalError("cannotAmendLocalPropertyDefinition")
                  .withSourceSection(createSourceSection(body.get(0)))
                  .build();
            }
            bodyNode =
                doVisitObjectBody(
                    body,
                    new ReadSuperPropertyNode(
                        unavailableSourceSection(),
                        scope.getName(),
                        // Never need a const check for amends declarations. In `foo { ... }`:
                        // 1. if `foo` is const, i.e. `const foo { ... }`, `super.foo` is required
                        // to be const (the const-ness of a property cannot be changed)
                        // 2. if in a const scope (i.e. `const bar = new { foo { ... } }`),
                        // `super.foo` does not reference something outside the scope.
                        false));
          } else { // foo = ...
            assert expr != null;

View on GitHub (pinned to f3efcbfc9b)