apple/pkl · error · VmException
objectCannotHaveProperty
objectCannotHaveProperty
Error message
Object of type `{0}` cannot have a property (other than `default`). What it means
Only `default` (and local) properties may be set on objects that aren't Dyanamic — e.g. typed class instances, List/Set/Map values, or functions. The generic fallback of GeneratorPropertyNode rejects any other property assignment with the object's type.
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/generator/GeneratorPropertyNode.java:90
@SuppressWarnings("unused")
@Specialization(guards = {"parent == getListingClass()", "checkIsValidListingProperty()"})
protected void evalListingClass(VirtualFrame frame, VmClass parent, ObjectData data) {
data.addProperty(frame, member, this);
}
@SuppressWarnings("unused")
@Specialization(
guards = {"isTypedObjectClass(parent)", "checkIsValidTypedProperty(parent, member)"})
protected void evalTypedObjectClass(VirtualFrame frame, VmClass parent, ObjectData data) {
data.addProperty(frame, member, this);
}
@Fallback
@SuppressWarnings("unused")
void fallback(Object parent, ObjectData data) {
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder()
.evalError(
"objectCannotHaveProperty",
parent instanceof VmClass ? parent : VmUtils.getClass(parent))
.withSourceSection(member.getHeaderSection())
.build();
}
@Idempotent
protected boolean checkIsValidListingProperty() {
if (member.isLocal() || member.getName() == Identifier.DEFAULT) return true;
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder()
.evalError("objectCannotHaveProperty", BaseModule.getListingClass())
.withSourceSection(member.getHeaderSection())
.build();
}
View on GitHub (pinned to f3efcbfc9b)
Solutions
- Remove the property or change it to `default` if overriding the object's default value is intended.
- Mark the member `local` if it's an internal helper that must not appear on the object.
- If the target should accept arbitrary properties, ensure it is a Dynamic (or the class declares the property).
Example fix
// before
myList { extra = 1 }
// after
local extra = 1
myList { ... } Defensive patterns
Strategy: type-guard
Validate before calling
// Only assign named properties to Dynamic/module objects
if (target is Dynamic || target is Module) {
// named property assignment is safe
} Type guard
function acceptsProperties(v: Any): Boolean = v is Dynamic || v is Module
Prevention
- Don't add properties to List/Set/Map or typed-class amendments.
- Use `local` bindings for helpers inside any object body.
- Only `default` may be overridden on non-Dynamic objects.
When it happens
Trigger: Amending a typed object or non-Dynamic value with a named property (`value { foo = 1 }`) where the parent type's fallback path is hit — parent is neither Dynamic, Listing, Mapping, nor Module. Raised in the public `fallback` node.
Common situations: Adding properties to a List or Map amendment; trying to override a property on a typed class instance that doesn't declare it; amending a base value like Int/String as if it were an object.
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
- classMustBeLocal
- typeAliasMustBeLocal
- nonLocalObjectPropertyCannotHaveTypeAnnotation
- externalMemberCannotHaveBody
- cannotAmendPropertyDefinition
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/16451ffa5f040b46.
Report an issue: GitHub.