{"record":{"id":"d525679e94d684c0","repo":"karatelabs/karate","slug":"cannot-add-property-name-object-is-not-extensible","errorCode":null,"errorMessage":"Cannot add property {name}, object is not extensible","messagePattern":"Cannot add property (.+?), object is not extensible","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsObject.java","lineNumber":483,"sourceCode":"        if (s != null && s.tombstoned) {\n            props.remove(name);\n        }\n    }\n\n    /** True iff {@code name} has a non-tombstoned own slot (excludes intrinsics). */\n    boolean ownContainsKey(String name) {\n        PropertySlot s = props == null ? null : props.get(name);\n        return s != null && !s.tombstoned;\n    }\n\n    /** Strict-mode [[Set]] rejection: assigning a non-writable / frozen prop. */\n    static void failReadOnly(String name) {\n        throw JsErrorException.typeError(\"Cannot assign to read only property '\" + name + \"'\");\n    }\n\n    /** Strict-mode [[Set]] rejection: adding a key to a non-extensible object. */\n    static void failNotExtensible(String name) {\n        throw JsErrorException.typeError(\"Cannot add property \" + name + \", object is not extensible\");\n    }\n\n    /** Strict-mode [[Delete]] rejection: removing a non-configurable property. */\n    static void failNotConfigurable(String name) {\n        throw JsErrorException.typeError(\"Cannot delete property '\" + name + \"' of \" + \"[object Object]\");\n    }\n\n    @Override\n    public void putMember(String name, Object value) {\n        putMember(name, value, null, false);\n    }\n\n    @Override\n    public void putMember(String name, Object value, CoreContext ctx, boolean strict) {\n        if (\"__proto__\".equals(name)) {\n            if (value instanceof ObjectLike proto) {\n                this.__proto__ = proto;\n            } else if (value == null) {","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsObject.java#L465-L501","documentation":"failNotExtensible is the strict-mode rejection helper for adding a string-keyed property to an object that is not extensible (frozen, sealed, or preventExtensions'd). Spec [[Set]] requires a TypeError in strict code; sloppy mode silently ignores the write.","triggerScenarios":"Strict-mode obj.newProp = value where obj was passed to Object.freeze, Object.seal, or Object.preventExtensions and newProp does not already exist on it.","commonSituations":"Freezing test fixtures or config then augmenting them; preventExtensions on objects used as ad-hoc maps; code migrating from sloppy to strict (module) code where silent failures become TypeErrors.","solutions":["Remove the freeze/seal/preventExtensions call if the object must grow","Pre-declare all needed properties before freezing","Use a Map or a fresh mutable object instead of the frozen one"],"exampleFix":"// before\nvar o = Object.preventExtensions({a: 1});\no.b = 2; // TypeError\n// after\nvar o = {a: 1, b: undefined};\no.b = 2;","handlingStrategy":"validation","validationCode":"if (!Object.isExtensible(o)) throw new TypeError('cannot add property to non-extensible object');","typeGuard":"function canAddProp(o) { return Object.isExtensible(o); }","tryCatchPattern":"try { o[name] = v; } catch (e) { if (String(e).includes('not extensible')) { o = {...o, [name]: v}; } else { throw e; } }","preventionTips":["Call freeze/seal/preventExtensions only after object shape is final","Check Object.isExtensible before adding keys in strict modules","Use Map instead of frozen objects as dynamic containers"],"tags":["javascript","strict-mode","typeerror","frozen-object","karate-js"],"backgroundTag":"object-not-extensible","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"}