{"record":{"id":"3ffd06e56f23dbc2","repo":"karatelabs/karate","slug":"cannot-delete-property-on-javautils-jstypename-object","errorCode":null,"errorMessage":"cannot delete property on ${JavaUtils.jsTypeName(object.getClass())}","messagePattern":"cannot delete property on (.+?)","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JavaObject.java","lineNumber":79,"sourceCode":"    @Override\n    public Object getMember(String name) {\n        return JavaUtils.convertIfArray(JavaUtils.get(object, name));\n    }\n\n    @Override\n    public Object getPropertyOrNotFound(String name) {\n        Object result = JavaUtils.getOrNotFound(object, name);\n        return result == JavaUtils.NOT_FOUND ? result : JavaUtils.convertIfArray(result);\n    }\n\n    @Override\n    public void putMember(String name, Object value) {\n        JavaUtils.set(object, name, value);\n    }\n\n    @Override\n    public void removeMember(String name) {\n        throw JsErrorException.typeError(\"cannot delete property on \" + JavaUtils.jsTypeName(object.getClass()));\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    public Map<String, Object> toMap() {\n        return (Map<String, Object>) JavaUtils.toMap(object);\n    }\n\n}\n\n","sourceCodeStart":61,"sourceCodeEnd":90,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JavaObject.java#L61-L90","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["If it is a java.util.Map, call `map.remove('key')` instead of `delete map.key`.","Convert to a plain JS object first, then delete: `var obj = karate.toMap(...)` / JSON round-trip, then `delete obj.field`.","Create a shallow copy in JS without the unwanted key and use that instead.","Move deletion to Java-side code if the object is host-owned."],"exampleFix":"// before\ndelete myJavaMap.someKey;\n// after\nvar obj = JSON.parse(JSON.stringify(karate.toJson(myJavaMap)));\ndelete obj.someKey;","handlingStrategy":"try-catch","validationCode":"if (typeof obj.deleteMember === 'function' || !(obj instanceof Java.type('java.lang.Object'))) { /* JS object: safe to delete */ }","typeGuard":"function isDeletableJsObject(o) { return o != null && !(o instanceof Java.type('java.lang.Object')); }","tryCatchPattern":"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; } }","preventionTips":["Use Map.remove(key) on java.util.Map instances instead of JS delete","Convert Java objects to plain JS/JSON before mutating structure","Treat wrapped Java objects as read-only from JS"],"tags":["javascript","java-interop","delete-operator","typeerror"],"backgroundTag":"unsupported-operation","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"}