{"record":{"id":"0a76460343fabe53","repo":"karatelabs/karate","slug":"cannot-assign-to-read-only-property-name-jsobject","errorCode":null,"errorMessage":"Cannot assign to read only property '{name}'","messagePattern":"Cannot assign to read only property '(.+?)'","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsObject.java","lineNumber":478,"sourceCode":"\n    /** Removes the tombstone for {@code name} if any. Subclasses use this when\n     *  a write reanimates a previously-deleted entry. */\n    void clearTombstone(String name) {\n        PropertySlot s = props == null ? null : props.get(name);\n        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","sourceCodeStart":460,"sourceCodeEnd":496,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsObject.java#L460-L496","documentation":"failReadOnly is the shared strict-mode rejection helper for string-keyed properties: putMember detects a non-writable slot and calls it, throwing the standard 'Cannot assign to read only property' TypeError as mandated by strict-mode [[Set]].","triggerScenarios":"Strict-mode obj.prop = value (or obj[name] = value) where prop exists with writable:false, or the object is frozen with the property still present.","commonSituations":"Object.freeze on constants/config objects then mutating them; Object.defineProperty omitting writable (defaults false); mutating imported/module-level frozen objects; strict-mode modules/functions in the Karate JS engine.","solutions":["Unfreeze the object or define the property writable:true if mutation is intended","Create a mutable copy (structuredClone / spread) instead of mutating the frozen original","Guard with Object.getOwnPropertyDescriptor check before writing"],"exampleFix":"// before\nvar o = Object.freeze({mode: 'x'});\no.mode = 'y'; // TypeError\n// after\nvar o = {mode: 'x'}; // keep mutable, or clone before writing\nvar copy = {...o}; copy.mode = 'y';","handlingStrategy":"validation","validationCode":"var d = Object.getOwnPropertyDescriptor(o, name); if (d && !d.writable) throw new TypeError('prop not writable: ' + name);","typeGuard":"function isWritableProp(o, name) { var d = Object.getOwnPropertyDescriptor(o, name); return !d || d.writable === true; }","tryCatchPattern":"try { o[name] = v; } catch (e) { if (String(e).includes('read only property')) { o = {...o, [name]: v}; } else { throw e; } }","preventionTips":["Don't freeze objects that are mutated downstream","Always specify writable:true explicitly when using Object.defineProperty","Clone frozen inputs before mutation"],"tags":["javascript","strict-mode","typeerror","readonly","frozen-object","karate-js"],"backgroundTag":"readonly-property-assignment","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"}