{"record":{"id":"b1ce4a524cc6d536","repo":"karatelabs/karate","slug":"cannot-set-property-on-null-super-base","errorCode":null,"errorMessage":"cannot set property on null 'super' base","messagePattern":"cannot set property on null 'super' base","errorType":"exception","errorClass":"JsErrorException (typeError)","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java","lineNumber":336,"sourceCode":"                // Same slot-or-name routing as set(): a scope-confined let/const\n                // is reachable only through its stamped slot — it has no byName\n                // entry, so a name-keyed update would miss it and fall through to\n                // an outer binding or an implicit global.\n                set(node, context, value, trackingNode);\n                yield value;\n            }\n            case REF_DOT_EXPR, REF_BRACKET_EXPR -> {\n                AccessSite site = resolveWriteSite(node, context);\n                if (context.isStopped()) yield Terms.UNDEFINED;\n                Object value = Interpreter.eval(rhsNode, context);\n                if (site == null || site == SHORT_CIRCUIT_SITE || context.isStopped()) yield value;\n                if (site.target == null && node.getFirst().type == NodeType.SUPER_EXPR) {\n                    // A super reference whose home object has a null [[Prototype]]\n                    // resolves to a null base; PutValue on it is a TypeError —\n                    // AFTER the RHS has been evaluated (hence not in\n                    // resolveWriteSite). Without this, setByName's null-target\n                    // fallback would treat the write as a scope update.\n                    throw JsErrorException.typeError(\"cannot set property on null 'super' base\");\n                }\n                if (site.privateName != null) PrivateAccess.set(site.target, site.privateName, value, context);\n                else siteWrite(site, value, context, trackingNode);\n                yield value;\n            }\n            default -> throw JsErrorException.typeError(\"cannot set on: \" + node);\n        };\n    }\n\n    /**\n     * Compound assignment (`op=`, e.g. +=, -=, *=) in spec §13.15 order:\n     * resolve the LHS Reference, GetValue it, and only then evaluate the RHS —\n     * a computed-key or getter side effect precedes any RHS side effect, and\n     * an abrupt completion at each step skips the rest. Returns the new value.\n     */\n    static Object compound(Node node, CoreContext context, TokenType operator, Node rhsNode, Node trackingNode) {\n                return switch (node.type) {\n            case REF_EXPR -> {","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java#L318-L354","documentation":"In `super.prop = value` assignments, if the superclass lookup finds the home object's [[Prototype]] is null, there is no base object to write to. The engine deliberately raises this TypeError only after the RHS is evaluated (matching PutValue ordering) rather than treating it as a scope update.","triggerScenarios":"A derived class method executes `super.x = v` while the class's home object has a null prototype (e.g. `Object.setPrototypeOf(cls.prototype, null)` or a class created without a proper prototype chain).","commonSituations":"Manual prototype surgery that nulls the parent; classes built via exotic factories without correct prototypes; framework code that resets prototype chains.","solutions":["Restore the class's prototype chain so [[Prototype]] is not null.","Avoid `setPrototypeOf(..., null)` on classes using `super` property writes.","Replace `super.x = v` with an explicit write to the intended parent object when exotic hierarchies are in play."],"exampleFix":"// before\nObject.setPrototypeOf(Derived.prototype, null); // super.x = 1 now throws\n// after\nObject.setPrototypeOf(Derived.prototype, Base.prototype);","handlingStrategy":"validation","validationCode":"// ensure the class prototype chain is intact before using super writes\nif (Object.getPrototypeOf(Derived.prototype) === null) throw new Error('Derived has null prototype; super writes will fail');","typeGuard":"function hasSuperBase(C) { return Object.getPrototypeOf(C.prototype) !== null; }","tryCatchPattern":"try { instance.step(); } catch (e) { if (String(e.message).includes(\"null 'super' base\")) { restorePrototype(instance.constructor); } else { throw e; } }","preventionTips":["Never setPrototypeOf(..., null) on classes that use super.","Preserve prototype chains in class factories and frameworks.","Prefer composition over manual prototype surgery when super writes are involved."],"tags":["javascript","super","prototype","type-error"],"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-19T12:17:13.211Z"}