karatelabs/karate · error · JsErrorException (typeError)
Cannot private member from an object whose class did not…
Error message
Cannot ${verb} private member ${pn.name} from an object whose class did not declare it What it means
`PrivateAccess.branded` implements the spec's brand check: before reading or writing a private member, the target object must actually have that private member installed by its class. Objects of other classes (or non-objects) fail the check and get this TypeError, keeping `#` members truly private across classes.
Solutions
- Invoke the method on a genuine instance of the declaring class instead of via call/apply/bind.
- Ensure the object passed in was constructed by the class that declares the private member.
- If duck-typing is intended, use public properties or symbols instead of `#private` ones.
- Add an `instanceof` check before invoking the private-member-using method.
Example fix
// before const m = a.getInstance; // borrowed method using this.#state m.call(b); // TypeError: Cannot read private member #state from an object whose class did not declare it // after a.getInstance(); // invoke on the declaring instance, or guard: if (x instanceof C) x.getInstance()
Defensive patterns
Strategy: type-guard
Validate before calling
// verify the receiver is an instance of the declaring class before invoking
if (!(target instanceof C)) throw new Error('method requires a C instance'); Type guard
function isBranded(x, C) { return x instanceof C; } Try / catch
try { return obj.method(); } catch (e) { if (e instanceof TypeError && /did not declare it/.test(e.message)) { return foreignImpl(obj); } throw e; } Prevention
- Never call/apply/bind `#`-member methods onto foreign objects.
- Require class instances (validate with instanceof) at API boundaries.
- Use public members or symbols for duck-typed cross-class sharing.
- Watch for destructuring that detaches methods from their instance.
When it happens
Trigger: Calling a method that reads `this.#x` with `this` bound to a foreign object (e.g. `OtherClass.prototype.method.call(notAnInstance)`, `Function.prototype.call/apply/bind` misuse, or destructuring a method off its instance).
Common situations: Borrowing methods between similar classes; passing plain objects where class instances are expected; mocking frameworks replacing `this`; using `.call()` to run a class method against a mock.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- ' ' was defined without a getter
- Cannot write to private method
- ' ' was defined without a setter
- toBytes() argument must be a list of numbers, got
- toBytes() list must contain only numbers, got
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/c5d5eb8972be7941.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/PrivateAccess.java:82
static void set(Object target, PrivateName pn, Object value, CoreContext context) {
JsObject obj = branded(target, pn, "write");
switch (pn.kind) {
case FIELD -> obj.putPrivate(pn, value);
case METHOD -> throw JsErrorException.typeError("Cannot write to private method " + pn.name);
case ACCESSOR -> {
if (pn.setter == null) {
throw JsErrorException.typeError("'" + pn.name + "' was defined without a setter");
}
Interpreter.invokeSetter(pn.setter, target, value, context);
}
}
}
private static JsObject branded(Object target, PrivateName pn, String verb) {
if (target instanceof JsObject obj && obj.hasPrivate(pn)) {
return obj;
}
throw JsErrorException.typeError("Cannot " + verb + " private member " + pn.name
+ " from an object whose class did not declare it");
}
}
View on GitHub (pinned to a22eb90246)