karatelabs/karate · error · JsErrorException
Cannot assign to read only property
Error message
Cannot assign to read only property '{sym}' What it means
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.
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
Example fix
// before
Object.defineProperty(o, sym, {value: 1, writable: false});
o[sym] = 2; // TypeError
// after
Object.defineProperty(o, sym, {value: 1, writable: true, configurable: true});
o[sym] = 2; Defensive patterns
Strategy: try-catch
Validate before calling
var d = Object.getOwnPropertyDescriptor(o, sym); if (d && !d.writable) throw new TypeError('slot not writable'); Type guard
function isWritableSym(o, sym) { var d = Object.getOwnPropertyDescriptor(o, sym); return !d || d.writable === true; } Try / catch
try { o[sym] = v; } catch (e) { if (String(e).includes('read only property')) { /* fallback: WeakMap metadata */ } else { throw e; } } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Cannot assign to read only property
- Cannot add property , object is not extensible
- Cannot delete property
- Cannot add property , object is not extensible
- Cannot delete property
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/4a2445d1218f6d2f.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsObject.java:232
* and anything else creates an own default-attribute slot. Mirrors what
* {@code setByName} + {@code putMember} do for string keys.
*/
void setSymbol(JsSymbol sym, Object value, CoreContext ctx, boolean strict) {
for (ObjectLike o = this; o != null; o = o.getPrototype()) {
if (!(o instanceof JsObject jo)) {
continue;
}
PropertySlot s = jo.ownSymbolSlot(sym);
if (s == null) {
continue;
}
if (s instanceof AccessorSlot acc) {
acc.write(this, value, ctx, strict);
return;
}
if (!s.isWritable()) {
if (strict) {
throw JsErrorException.typeError(
"Cannot assign to read only property '" + sym + "'");
}
return;
}
if (jo == this) {
s.write(this, value, ctx, strict);
return;
}
break; // inherited writable data property — shadow it with an own slot
}
if (frozen || sealed || nonExtensible) {
if (strict) {
throw JsErrorException.typeError(
"Cannot add property " + sym + ", object is not extensible");
}
return;
}
defineOwnSymbol(sym, value, PropertySlot.ATTRS_DEFAULT);View on GitHub (pinned to a22eb90246)