{"record":{"id":"96aafad4df2090c0","repo":"karatelabs/karate","slug":"cannot-write-to-private-method-pn-name","errorCode":null,"errorMessage":"Cannot write to private method ${pn.name}","messagePattern":"Cannot write to private method (.+?)","errorType":"exception","errorClass":"JsErrorException (typeError)","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/PrivateAccess.java","lineNumber":68,"sourceCode":"    static Object get(Object target, PrivateName pn, CoreContext context) {\n        JsObject obj = branded(target, pn, \"read\");\n        return switch (pn.kind) {\n            case FIELD -> obj.getPrivate(pn);\n            case METHOD -> pn.method;\n            case ACCESSOR -> {\n                if (pn.getter == null) {\n                    throw JsErrorException.typeError(\"'\" + pn.name + \"' was defined without a getter\");\n                }\n                yield Interpreter.invokeGetter(pn.getter, target, context);\n            }\n        };\n    }\n\n    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}","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/PrivateAccess.java#L50-L86","documentation":"`PrivateAccess.set` throws this TypeError when code assigns to a private method (`obj.#method = ...`). Private methods are immutable class members; the ES spec forbids writing to them, so the engine rejects the assignment instead of silently overwriting.","triggerScenarios":"An assignment expression whose LHS resolves to a private name of kind METHOD, e.g. `this.#run = fn` inside or against a class that declared `#run() {}` as a method.","commonSituations":"Attempting to monkey-patch a private method from within the class; typos where a field was intended (`#handler = ...`) but was declared as a method; refactors that converted fields to methods while old assignment code remained.","solutions":["Remove the assignment to the private method.","Change the declaration from a private method to a private field if rebinding is intended (`#run = () => {...}`).","Use a different private field to hold the replacement function instead of reassigning the method name."],"exampleFix":"// before\nclass C { #run() {} init() { this.#run = () => {}; } } // TypeError\n// after\nclass C { #run = () => {}; }","handlingStrategy":"validation","validationCode":"// ensure the target is a private field, not a method, before assigning\nconst isMethod = /#run\\s*\\(/.test(classSource);\nif (isMethod) throw new Error('cannot assign to private method #run');","typeGuard":"function isPrivateMethod(classSrc, name) { return new RegExp('#' + name + '\\\\s*\\\\(').test(classSrc); }","tryCatchPattern":"try { c.#run = fn; } catch (e) { if (e instanceof TypeError && /Cannot write to private method/.test(e.message)) { c = new CWithField(fn); } else { throw e; } }","preventionTips":["Never assign to `#method` names; use a separate private field for swappable behavior.","Declare configurable behavior as private fields initialized with functions.","Review refactors that convert fields to methods for lingering assignments."],"tags":["javascript","private-fields","type-error","immutability"],"backgroundTag":"invalid-state-transition","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"}