karatelabs/karate · error · ParserException
cannot delete private member
Error message
cannot delete private member ${name} What it means
Per the class-fields spec, `delete` is not permitted on private field/method/accessor references. Karate's parser statically detects a PRIVATE_NAME key in a dot-reference under a DELETE_EXPR and rejects it at parse time, because deleting a private member would break class encapsulation invariants.
Solutions
- Remove the delete statement and instead assign a sentinel (e.g. `obj.#field = null`) if the field's semantics allow it
- Expose an explicit class method that performs the invalidation/reset the private member needs
- If the property must be deletable, make it a regular (non-private) property
Example fix
// before delete obj.#cache; // after obj.#cache = null; // or call an explicit reset method
Defensive patterns
Strategy: validation
Validate before calling
// Scan for delete of private members: const hasBadDelete = /delete\s+(?:\(\s*)?[\w$.]*\.#\w+/.test(src);
Try / catch
try { eval(js); } catch (e) { if (String(e).includes('cannot delete private member')) { /* replace with assignment/nulling */ } throw e; } Prevention
- Treat private fields as non-configurable: never `delete` them
- Provide explicit reset/clear methods on the class
- Keep deletes limited to ordinary public properties
When it happens
Trigger: Writing `delete obj.#field;` (or the same inside parentheses) anywhere the parser runs privateNodeChecks. The check descends through PAREN_EXPR/EXPR/EXPR_LIST wrappers to find a REF_DOT_EXPR whose key token is a PRIVATE_NAME.
Common situations: Attempting to 'reset' or remove a private field on an object; porting code that deleted plain properties and mechanically adding `#`; misunderstanding private fields as configurable properties.
Related errors
- unexpected private name
- private name is not declared in an enclosing class
- unexpected logical-assignment operator
- unexpected operator
- parser state: [ ]
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/045c61411af9dda0.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/parser/JsParser.java:294
if (key != null && key.isToken() && key.token.type == PRIVATE_NAME) {
requirePrivateDeclared(key.getText(), privates);
}
}
case PRIVATE_NAME_EXPR -> {
Node parent = node.getParent();
if (parent == null || parent.type != NodeType.IN_EXPR || parent.getFirst() != node) {
throw new ParserException("unexpected private name '" + node.getText()
+ "': only valid as the left operand of `in`");
}
requirePrivateDeclared(node.getText(), privates);
}
case DELETE_EXPR -> {
Node target = node.size() > 1 ? node.get(1) : null;
while (target != null && !target.isToken()) {
if (target.type == NodeType.REF_DOT_EXPR) {
Node key = target.size() > 2 ? target.get(2) : null;
if (key != null && key.isToken() && key.token.type == PRIVATE_NAME) {
throw new ParserException("cannot delete private member " + key.getText());
}
break;
}
if (target.type == NodeType.PAREN_EXPR) {
target = target.size() > 1 ? target.get(1) : null;
} else if (target.type == NodeType.EXPR || target.type == NodeType.EXPR_LIST) {
target = target.size() == 1 ? target.getFirst() : null;
} else {
break;
}
}
}
default -> {
}
}
return privates;
}
View on GitHub (pinned to a22eb90246)