apple/pkl · error · VmException
cannotFindPropertyInObjectNoHint
cannotFindPropertyInObjectNoHint
Error message
Cannot find property `{0}` in object of type `{1}`. What it means
This error is raised when an explicit-receiver property read (`obj.prop`) is evaluated against a `VmReference` (a deferred/reference value in the Pkl runtime) and the referenced object does not expose a property with that name. `evalReference` calls `receiver.withPropertyAccess(propertyName)`, which throws a `VmReferenceAccessError` on a failed member lookup; Pkl converts it into a 'cannot find property' error and attaches a hint describing why the lookup failed (member not found, external member, default member, or external class).
Source
Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/member/ReadPropertyNode.java:94
ErrorMessages.create("cannotReferenceExternalProperty", propertyName, err.getType());
case DEFAULT_MEMBER ->
ErrorMessages.create(
"cannotReferenceDefaultProperty",
((PType.Class) err.getType()).getPClass().getSimpleName());
case EXTERNAL_CLASS ->
ErrorMessages.create(
"cannotReferencePropertyInExternalClass", propertyName, err.getType());
};
}
@Specialization
protected VmReference evalReference(VmReference receiver) {
assert lookupMode == MemberLookupMode.EXPLICIT_RECEIVER;
try {
return receiver.withPropertyAccess(propertyName);
} catch (VmReferenceAccessError err) {
CompilerDirectives.transferToInterpreter();
throw exceptionBuilder()
.evalError("cannotFindPropertyInObjectNoHint", propertyName, receiver.exportType())
.withHint(getReferenceErrorHint(receiver, err))
.build();
}
}
// This method effectively covers `VmObject receiver` but is implemented in a more
// efficient way. See:
// https://www.graalvm.org/22.0/graalvm-as-a-platform/language-implementation-framework/TruffleLibraries/#strategy-2-java-interfaces
@Specialization(guards = "receiver.getClass() == cachedClass", limit = "99")
protected Object evalObject(
Object receiver,
@Cached("getVmObjectSubclassOrNull(receiver)") Class<? extends VmObjectLike> cachedClass,
@Cached("create()") IndirectCallNode callNode) {
var object = cachedClass.cast(receiver);
checkConst(object);
var result = VmUtils.readMemberOrNull(object, propertyName, true, callNode);View on GitHub (pinned to f3efcbfc9b)
Solutions
- Read the error hint to see whether the property is missing, external, or default, then fix the property name on the reference read.
- Verify the property exists on the referent's exported type (check the module/class definition you are referencing).
- If the property is genuinely optional, guard with `'prop' in obj` or use `obj.getPropertyOrNull("prop")` style access instead of direct dot access.
- If a dependency module changed, update the consumer code or pin the dependency version.
Example fix
// before
import "myLib.pkl"
output { text = myLib.connctionUrl } // error: no property `connctionUrl`
// after
import "myLib.pkl"
output { text = myLib.connectionUrl } Defensive patterns
Strategy: validation
Validate before calling
// Pkl: verify a property exists on the referenced object before reading it function safeRead(obj: Object, key: String): any? = if (key in obj) obj[key] else null
Type guard
// Pkl: narrow before direct dot access function hasProp(obj: Object, key: String): Boolean = key in obj // only use obj.myProp when hasProp(obj, "myProp") is true
Try / catch
// Pkl CLI/eval hosts: wrap module evaluation and inspect VmException for cannotFindProperty errors
try {
evaluate(module)
} catch (e: PklException) {
if (e.message.contains("Cannot find property")) {
// fall back to defaults or report the missing key
}
} Prevention
- Rely on type-checked imports (`import "..."`) so unknown property names fail at type-check time.
- Check the referent module's declared properties before dot-accessing through references.
- Use `key in obj` or `obj[key]` for potentially absent properties.
When it happens
Trigger: Occurs when reading a property through an explicit receiver on a reference-typed value where the property does not exist on the referent's type: e.g. `someModuleRef.typoProp`, accessing a property declared in a sibling type, or referencing an external/default property that cannot be resolved through the reference.
Common situations: Typo'd property names on typed module or object references; a provider module renamed or removed a property so downstream `import` consumers break; accessing a property that exists on the concrete type but not on the declared reference type; reading properties of `external` or default-valued members that the reference cannot access.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08).
Data as JSON: /api/errors/6f66e3908656739c.
Report an issue: GitHub.