{"record":{"id":"f68b964de69fbd65","repo":"apple/pkl","slug":"propertymustbeconst-f68b96","errorCode":"propertyMustBeConst","errorMessage":"Cannot reference property `{0}` from here because it is not `const`.","messagePattern":"Cannot reference property `(.+?)` from here because it is not `const`\\.","errorType":"error_code","errorClass":"VmException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/ast/expression/member/ReadSuperPropertyNode.java","lineNumber":60,"sourceCode":"    var receiver = VmUtils.getObjectReceiver(frame);\n\n    // start from the parent of the owner of the `super.<propertyName>` expression\n    // skip any function object owners (same as when resolving `this`)\n    // `receiver` must be passed on unchanged to make sure that overridden properties still take\n    // effect\n    var initialOwner = VmUtils.getOwner(frame);\n    while (initialOwner instanceof VmFunction) {\n      initialOwner = initialOwner.getEnclosingOwner();\n    }\n    assert initialOwner != null : \"VmFunction always has a parent\";\n    initialOwner = initialOwner.getParent();\n\n    for (var owner = initialOwner; owner != null; owner = owner.getParent()) {\n      var property = owner.getMember(propertyName);\n      if (property == null) continue;\n      if (needsConst && !property.isConst()) {\n        CompilerDirectives.transferToInterpreter();\n        throw exceptionBuilder().evalError(\"propertyMustBeConst\", propertyName.toString()).build();\n      }\n\n      var constantValue = property.getConstantValue();\n      if (constantValue != null) return constantValue; // TODO: type check\n\n      // caching the result of a super call is tricky (function of both receiver and owner)\n      return callNode.call(\n          property.getCallTarget(),\n          // TODO: should the marker only turn off constraint checking, not overall type checking?\n          receiver,\n          owner,\n          propertyName,\n          VmUtils.SKIP_TYPECHECK_MARKER);\n    }\n\n    // TODO: refine when to return VmDynamic.empty() and when to fail\n    return VmDynamic.empty();\n  }","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/ast/expression/member/ReadSuperPropertyNode.java#L42-L78","documentation":"ReadSuperPropertyNode resolves `super.prop` by walking up the owner chain from the current owner. When the read site requires a const value (needsConst), it rejects any resolved member that is not declared `const`, throwing propertyMustBeConst. This guarantees `super` references used in const contexts cannot observe values that differ per amending object.","triggerScenarios":"Writing `super.someProp` inside a `const` (or other needsConst) member where `someProp` is defined non-const in a parent class or enclosing object; executeGeneric walks owner.getParent() and finds the member but its isConst() is false.","commonSituations":"`const x: Int = super.baseValue` where the superclass declares `baseValue` as a normal property; migrating code that changed `super.foo` context to `fixed`/`const` after a refactor.","solutions":["Declare the parent's property `const` (e.g. `const baseValue: Int = 10` in the superclass)","Copy the needed value into a local const or literal instead of reading it via `super`","Change the reading member so it does not require const (drop the `const`/`fixed` qualifier)","Restructure inheritance so the const value lives in a shared const definition both classes reference"],"exampleFix":"// before\nopen class Base {\n  port: Int = 8080\n}\nclass Derived extends Base {\n  const defaultPort: Int = super.port // ERROR\n}\n// after\nopen class Base {\n  const port: Int = 8080\n}\nclass Derived extends Base {\n  const defaultPort: Int = super.port\n}","handlingStrategy":"validation","validationCode":"// before writing `super.prop` in a const member, confirm the superclass declares it const:\n// open class Base { const prop: Int = ... }","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Keep inherited values consumed via `super` declared `const` in base classes","Avoid `super` reads inside const/fixed members; use direct literal consts instead","Document const-ness contracts on open base classes"],"tags":["pkl","super","const-property"],"backgroundTag":"invalid-config-value","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}