karatelabs/karate · error · JsErrorException

cannot delete property on

Error message

cannot delete property on ${JavaUtils.jsTypeName(object.getClass())}

What it means

JavaObject wraps a plain Java object for the JS engine. Java objects do not support JS `delete` semantics, so removeMember unconditionally throws a TypeError naming the Java type. This prevents scripts from silently assuming a delete succeeded on a host object.

Solutions

  1. If it is a java.util.Map, call `map.remove('key')` instead of `delete map.key`.
  2. Convert to a plain JS object first, then delete: `var obj = karate.toMap(...)` / JSON round-trip, then `delete obj.field`.
  3. Create a shallow copy in JS without the unwanted key and use that instead.
  4. Move deletion to Java-side code if the object is host-owned.

Example fix

// before
delete myJavaMap.someKey;
// after
var obj = JSON.parse(JSON.stringify(karate.toJson(myJavaMap)));
delete obj.someKey;
Defensive patterns

Strategy: try-catch

Validate before calling

if (typeof obj.deleteMember === 'function' || !(obj instanceof Java.type('java.lang.Object'))) { /* JS object: safe to delete */ }

Type guard

function isDeletableJsObject(o) { return o != null && !(o instanceof Java.type('java.lang.Object')); }

Try / catch

try { delete wrapped.field; } catch (e) { if (String(e).indexOf('cannot delete property') !== -1) { var copy = JSON.parse(JSON.stringify(karate.toJson(wrapped))); delete copy.field; } else { throw e; } }

Prevention

When it happens

Trigger: Executing `delete someJavaObject.field` in a Karate JS block where someJavaObject is a wrapped plain Java object (e.g. a Java Map-backed value passed in, a variable created via `new` on a Java class, or karate.get of a Java object).

Common situations: Trying to remove a key from a java.util.Map with JS delete instead of .remove(key); cleaning up config objects that are Java-typed rather than JS/JSON objects.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/3ffd06e56f23dbc2. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/JavaObject.java:79

    @Override
    public Object getMember(String name) {
        return JavaUtils.convertIfArray(JavaUtils.get(object, name));
    }

    @Override
    public Object getPropertyOrNotFound(String name) {
        Object result = JavaUtils.getOrNotFound(object, name);
        return result == JavaUtils.NOT_FOUND ? result : JavaUtils.convertIfArray(result);
    }

    @Override
    public void putMember(String name, Object value) {
        JavaUtils.set(object, name, value);
    }

    @Override
    public void removeMember(String name) {
        throw JsErrorException.typeError("cannot delete property on " + JavaUtils.jsTypeName(object.getClass()));
    }

    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> toMap() {
        return (Map<String, Object>) JavaUtils.toMap(object);
    }

}

View on GitHub (pinned to a22eb90246)