{"record":{"id":"4a2445d1218f6d2f","repo":"karatelabs/karate","slug":"cannot-assign-to-read-only-property-sym","errorCode":null,"errorMessage":"Cannot assign to read only property '{sym}'","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":232,"sourceCode":"     * and anything else creates an own default-attribute slot. Mirrors what\n     * {@code setByName} + {@code putMember} do for string keys.\n     */\n    void setSymbol(JsSymbol sym, Object value, CoreContext ctx, boolean strict) {\n        for (ObjectLike o = this; o != null; o = o.getPrototype()) {\n            if (!(o instanceof JsObject jo)) {\n                continue;\n            }\n            PropertySlot s = jo.ownSymbolSlot(sym);\n            if (s == null) {\n                continue;\n            }\n            if (s instanceof AccessorSlot acc) {\n                acc.write(this, value, ctx, strict);\n                return;\n            }\n            if (!s.isWritable()) {\n                if (strict) {\n                    throw JsErrorException.typeError(\n                            \"Cannot assign to read only property '\" + sym + \"'\");\n                }\n                return;\n            }\n            if (jo == this) {\n                s.write(this, value, ctx, strict);\n                return;\n            }\n            break; // inherited writable data property — shadow it with an own slot\n        }\n        if (frozen || sealed || nonExtensible) {\n            if (strict) {\n                throw JsErrorException.typeError(\n                        \"Cannot add property \" + sym + \", object is not extensible\");\n            }\n            return;\n        }\n        defineOwnSymbol(sym, value, PropertySlot.ATTRS_DEFAULT);","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsObject.java#L214-L250","documentation":"In strict-mode JS code, assigning to a property that exists but is non-writable (e.g. defined with writable:false, or on a frozen object) must throw a TypeError per [[Set]]. Karate's JsObject.setSymbol enforces this for symbol-keyed properties; in sloppy mode the assignment is silently ignored.","triggerScenarios":"Strict-mode assignment obj[mySymbol] = value where the symbol property was defined non-writable, or the object was frozen and the property resolved read-only.","commonSituations":"Freezing shared/constant objects for safety then writing symbol-keyed metadata; Object.defineProperty with enumerable:true but writable:false; library-internal symbol slots treated as user-writable.","solutions":["Remove the freeze or the writable:false restriction if mutation is intended","Use Object.defineProperty to redefine the property as writable before assigning","Wrap the assignment in try/catch if it is best-effort"],"exampleFix":"// before\nObject.defineProperty(o, sym, {value: 1, writable: false});\no[sym] = 2; // TypeError\n// after\nObject.defineProperty(o, sym, {value: 1, writable: true, configurable: true});\no[sym] = 2;","handlingStrategy":"try-catch","validationCode":"var d = Object.getOwnPropertyDescriptor(o, sym); if (d && !d.writable) throw new TypeError('slot not writable');","typeGuard":"function isWritableSym(o, sym) { var d = Object.getOwnPropertyDescriptor(o, sym); return !d || d.writable === true; }","tryCatchPattern":"try { o[sym] = v; } catch (e) { if (String(e).includes('read only property')) { /* fallback: WeakMap metadata */ } else { throw e; } }","preventionTips":["Define symbol slots with writable:true when mutation is expected","Avoid freezing objects that receive symbol metadata","Check descriptor writability in strict code before writing"],"tags":["javascript","strict-mode","typeerror","readonly","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"}