apple/pkl · error · VmException

cannotFindMember on object

Error message

cannotFindMember ${key} on object

What it means

Thrown when a subscript/bracket read on a Pkl object does not resolve to any member: the object has no property or element matching the given key. It is Pkl's equivalent of a 'member not found' error for dynamic member reads (`VmUtils.readMemberOrNull` returned null).

Solutions

  1. Fix the key name (check the exact spelling in the error)
  2. Declare the property on the object or its class before reading it
  3. Use `obj[key] ?? default` style defaulting where the API allows, or check with `containsKey`-style helpers
  4. Verify the intended amendment/module is actually imported and applied

Example fix

// before
port = config["prot"]
// after
port = config["port"] ?? 8080
Defensive patterns

Strategy: type-guard

Validate before calling

// pkl
exists = obj.hasProperty("key") // or containsKey for mappings
value = if (exists) obj["key"] else default

Type guard

function hasMember(obj, key) { return obj != null && key in obj }

Try / catch

// catch member-not-found and supply a default value

Prevention

When it happens

Trigger: Evaluating `obj[key]` or dynamic member read where `key` matches no property of the object; e.g. reading a config field that was never declared, or a typo in the key name.

Common situations: Typos in config keys, expecting a property added by an amendment that wasn't applied, reading optional fields without a default, schema drift between producer and consumer of a config.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/ast/expression/binary/SubscriptNode.java:152

  @Specialization
  protected long eval(VmBytes receiver, long index) {
    if (index < 0 || index >= receiver.getLength()) {
      CompilerDirectives.transferToInterpreter();
      throw exceptionBuilder()
          .evalError("elementIndexOutOfRange", index, 0, receiver.getLength() - 1)
          .withProgramValue("Value", receiver)
          .build();
    }
    return receiver.get(index);
  }

  private Object readMember(VmObject object, Object key, IndirectCallNode callNode) {
    var result = VmUtils.readMemberOrNull(object, key, callNode);
    if (result != null) return result;

    CompilerDirectives.transferToInterpreter();
    throw exceptionBuilder().cannotFindMember(object, key).build();
  }
}

View on GitHub (pinned to f3efcbfc9b)