karatelabs/karate · error · JsErrorException (typeError)
cannot apply pre inc/dec to
Error message
cannot apply pre inc/dec to: ${node} What it means
A TypeError thrown when a pre-increment/decrement operator is applied to a node type the evaluator does not support as an update target. Valid targets are variable references, property accesses (with private/super/index/name handling), and literals are simply not reachable here; anything else hits the default arm.
Solutions
- Rewrite the target as a variable or property: `++obj.count`
- Store the expression in a variable, then apply `++` to that variable
- If the source is valid, check for a parser regression and upgrade
Example fix
// before ++(x + y); // after let s = x + y; ++s;
Defensive patterns
Strategy: validation
Validate before calling
// Reject pre-inc/dec on non-assignable expressions before eval
if (/\+\+\s*[(\d'"]|--\s*[(\d'"]/.test(code)) { /* invalid pre-inc/dec target */ } Type guard
function isPreIncDecTarget(node) {
return node && ['Identifier','MemberExpression'].includes(node.type);
} Prevention
- Apply ++/-- only to variables or properties
- Rewrite `++call()` patterns into explicit assign-then-increment
- Validate generated ASTs before interpretation
When it happens
Trigger: Executing `++expr`/`--expr` where expr parses as an unsupported node shape — e.g. `++(a, b)`, `++foo()`, or a malformed AST node from a parser defect.
Common situations: Hand-written invalid JS like `++obj.getMethod()`; code generators or transpilers emitting bad increment targets; parser/interpreter version skew.
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
- cannot apply compound assignment to
- cannot apply logical-assignment to
- cannot apply post inc/dec to
- cannot get from
- cannot set on
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/dbd69b8f56687bca.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java:596
throw SlotTable.tdzError(node.getText());
}
Object step = Terms.incDecStep(oldValue);
Object newValue = isIncrement ? Terms.add(oldValue, step, context) : Terms.min(oldValue, step, context);
context.updateSlot(slot, newValue, null);
yield newValue;
}
yield incDecRefByName(node, context, isIncrement, true);
}
case REF_DOT_EXPR, REF_BRACKET_EXPR -> {
AccessSite site = resolveWriteSite(node, context);
if (site == null || site == SHORT_CIRCUIT_SITE) yield Terms.UNDEFINED;
if (site.privateName != null) yield privateIncDec(site, isIncrement, true, context);
if (site.receiver != null) yield superIncDec(site, isIncrement, true, context);
yield site.isIndex
? preIncDecByIndex(site.target, site.key, isIncrement, context)
: preIncDecByName(site.target, (String) site.key, isIncrement, context);
}
default -> throw JsErrorException.typeError("cannot apply pre inc/dec to: " + node);
};
}
/**
* Delete a property. Returns true on success.
*/
static boolean delete(Node node, CoreContext context) {
return switch (node.type) {
case REF_EXPR -> false; // Can't delete variables
case REF_DOT_EXPR, REF_BRACKET_EXPR -> {
AccessSite site;
try {
site = resolveWriteSite(node, context);
} catch (JsErrorException e) {
// delete on `?.()` shape: legacy behavior was to return false silently
yield false;
}
// a short-circuited chain leaves no reference to delete, whichView on GitHub (pinned to a22eb90246)