apple/pkl · error · VmException

cannotFindPropertyInObject

cannotFindPropertyInObject

Error message

Cannot find property `{0}` in object of type `{1}`.

What it means

Thrown when a property access `receiver.prop` on a Pkl object (VmObjectLike) finds no member named `prop`, even when walking default and external members (`readMemberOrNull` with forceLookup). After const-checking the receiver, `evalObject` attempts the member read; a null result means the property is absent from the object's class chain, so Pkl raises 'cannot find property' against the object. This is the standard dynamic property-miss error for object receivers.

Source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/member/ReadPropertyNode.java:116

    }
  }

  // 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);
    if (result != null) return result;

    CompilerDirectives.transferToInterpreter();
    throw cannotFindProperty(object);
  }

  // specializations for all other types
  @Specialization(guards = "receiver.getClass() == cachedClass", limit = "99")
  protected Object evalOther(
      Object receiver,
      @Cached("receiver.getClass()") @SuppressWarnings("unused") Class<?> cachedClass,
      @Cached("resolveProperty(receiver)") ClassProperty resolvedProperty,
      @Cached("createCallNode(resolvedProperty)") DirectCallNode callNode) {

    return callNode.call(receiver, resolvedProperty.getOwner(), resolvedProperty.getName());
  }

  protected static @Nullable Class<? extends VmObjectLike> getVmObjectSubclassOrNull(Object value) {
    // OK to perform slow cast here (not a guard)
    return value instanceof VmObjectLike objectLike ? objectLike.getClass() : null;
  }

View on GitHub (pinned to f3efcbfc9b)

Solutions

  1. Fix the property name in the read site (check spelling and the object's actual definition).
  2. Add the missing property to the object being read (define it in the class or amend the object).
  3. Use a safe access pattern (`obj["prop"]` with existence check, or `if ("prop" in obj)`) when the property may be absent.
  4. Pin or update the dependency package version so the class still declares the expected property.

Example fix

// before
server {
  host = "localhost"
}
val url = server.protocol + "://" + server.host // error: no property `protocol`

// after
server {
  host = "localhost"
  protocol = "https"
}
val url = server.protocol + "://" + server.host
Defensive patterns

Strategy: validation

Validate before calling

// Pkl: guard dynamic property reads on objects
function readOrNull(obj: Object, key: String): any? =
  if (key in obj) obj[key] else null

Type guard

// Pkl: narrow object shape before member access
function isServerConfig(obj: Object): Boolean =
  "host" in obj && "port" in obj

Try / catch

// Host-side (Java) embedders: catch the evaluation exception and match the error code
try {
  evaluator.evaluateOutput(moduleSource)
} catch (e: PklBugException | EvaluationException e) {
  if (e.getMessage().contains("Cannot find property")) {
    // supply default or surface a friendly message
  }
}

Prevention

When it happens

Trigger: Occurs when evaluating `obj.propName` where `obj` is a Pkl object/module and no property `propName` is declared on it or any of its supertypes — e.g. accessing an undefined field on an amending object, a module-level property that was never defined, or a property removed from a stdlib/dependency class.

Common situations: Typos in property names in config files; expecting a base class property to be inherited when it is defined only on a sibling class; upgrading a package whose classes dropped or renamed properties; accessing output/stdlib properties that moved between Pkl versions; reading a property on an object literal that only defines different keys.

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/bf7d78dafade4c30. Report an issue: GitHub.