{"record":{"id":"c5d5eb8972be7941","repo":"karatelabs/karate","slug":"cannot-verb-private-member-pn-name-from-an-object-whose","errorCode":null,"errorMessage":"Cannot ${verb} private member ${pn.name} from an object whose class did not declare it","messagePattern":"Cannot (.+?) private member (.+?) from an object whose class did not declare it","errorType":"exception","errorClass":"JsErrorException (typeError)","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/PrivateAccess.java","lineNumber":82,"sourceCode":"    static void set(Object target, PrivateName pn, Object value, CoreContext context) {\n        JsObject obj = branded(target, pn, \"write\");\n        switch (pn.kind) {\n            case FIELD -> obj.putPrivate(pn, value);\n            case METHOD -> throw JsErrorException.typeError(\"Cannot write to private method \" + pn.name);\n            case ACCESSOR -> {\n                if (pn.setter == null) {\n                    throw JsErrorException.typeError(\"'\" + pn.name + \"' was defined without a setter\");\n                }\n                Interpreter.invokeSetter(pn.setter, target, value, context);\n            }\n        }\n    }\n\n    private static JsObject branded(Object target, PrivateName pn, String verb) {\n        if (target instanceof JsObject obj && obj.hasPrivate(pn)) {\n            return obj;\n        }\n        throw JsErrorException.typeError(\"Cannot \" + verb + \" private member \" + pn.name\n                + \" from an object whose class did not declare it\");\n    }\n\n}\n","sourceCodeStart":64,"sourceCodeEnd":87,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/PrivateAccess.java#L64-L87","documentation":"`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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nconst m = a.getInstance; // borrowed method using this.#state\nm.call(b); // TypeError: Cannot read private member #state from an object whose class did not declare it\n// after\na.getInstance(); // invoke on the declaring instance, or guard: if (x instanceof C) x.getInstance()","handlingStrategy":"type-guard","validationCode":"// verify the receiver is an instance of the declaring class before invoking\nif (!(target instanceof C)) throw new Error('method requires a C instance');","typeGuard":"function isBranded(x, C) { return x instanceof C; }","tryCatchPattern":"try { return obj.method(); } catch (e) { if (e instanceof TypeError && /did not declare it/.test(e.message)) { return foreignImpl(obj); } throw e; }","preventionTips":["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."],"tags":["javascript","private-fields","type-error","brand-check"],"backgroundTag":"type-mismatch","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}