karatelabs/karate · error · JsErrorException
Cannot delete property
Error message
Cannot delete property '{name}' of [object Object] What it means
failNotConfigurable implements strict-mode [[Delete]] rejection for string-keyed properties: deleting an existing non-configurable property throws a TypeError, whereas sloppy delete would just return false. The message includes the receiver's toStringTag for context.
Solutions
- Avoid deleting; assign undefined (and/or null out the value) instead if configurability can't change
- Redefine the property with configurable:true first (possible only if it is currently configurable), then delete
- Clone the object minus the key ({[k]: v} rest spread / structuredClone + delete on the copy)
Example fix
// before
var o = Object.freeze({token: 'abc'});
delete o.token; // TypeError
// after
var o = {token: 'abc'};
var {token, ...rest} = o; // non-mutating removal Defensive patterns
Strategy: try-catch
Validate before calling
var d = Object.getOwnPropertyDescriptor(o, name); if (d && !d.configurable) throw new TypeError('prop not configurable: ' + name); Type guard
function isConfigurableProp(o, name) { var d = Object.getOwnPropertyDescriptor(o, name); return !d || d.configurable === true; } Try / catch
try { delete o[name]; } catch (e) { if (String(e).includes('Cannot delete property')) { o[name] = undefined; } else { throw e; } } Prevention
- Prefer assigning undefined over delete for non-configurable slots
- Pass configurable:true in defineProperty for removable fields
- Use rest-spread destructuring for non-mutating key removal
When it happens
Trigger: Strict-mode delete obj.prop where prop is an own non-configurable property (Object.defineProperty default, frozen/sealed object properties, or built-in slots).
Common situations: Deleting properties of a frozen object during cleanup; Object.defineProperty used without configurable:true; sanitizing third-party objects that expose non-configurable fields; strict-mode code where sloppy deletes previously 'succeeded' silently.
Related errors
- Cannot add property , object is not extensible
- Cannot delete property
- Cannot assign to read only property
- Cannot add property , object is not extensible
- Cannot assign to read only property
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/9d0e5c6a58863c86.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsObject.java:488
/** True iff {@code name} has a non-tombstoned own slot (excludes intrinsics). */
boolean ownContainsKey(String name) {
PropertySlot s = props == null ? null : props.get(name);
return s != null && !s.tombstoned;
}
/** Strict-mode [[Set]] rejection: assigning a non-writable / frozen prop. */
static void failReadOnly(String name) {
throw JsErrorException.typeError("Cannot assign to read only property '" + name + "'");
}
/** Strict-mode [[Set]] rejection: adding a key to a non-extensible object. */
static void failNotExtensible(String name) {
throw JsErrorException.typeError("Cannot add property " + name + ", object is not extensible");
}
/** Strict-mode [[Delete]] rejection: removing a non-configurable property. */
static void failNotConfigurable(String name) {
throw JsErrorException.typeError("Cannot delete property '" + name + "' of " + "[object Object]");
}
@Override
public void putMember(String name, Object value) {
putMember(name, value, null, false);
}
@Override
public void putMember(String name, Object value, CoreContext ctx, boolean strict) {
if ("__proto__".equals(name)) {
if (value instanceof ObjectLike proto) {
this.__proto__ = proto;
} else if (value == null) {
this.__proto__ = null;
}
return;
}
// Frozen: ignore all writes (sloppy); strict throws. Non-extensible:View on GitHub (pinned to a22eb90246)