karatelabs/karate · error · JsErrorException (typeError)
cannot apply compound assignment to
Error message
cannot apply compound assignment to: ${node} What it means
A TypeError thrown when a compound-assignment expression (`+=`, `-=`, `*=`, etc.) is applied to a parse-tree node type the evaluator does not support as an assignment target. Only variable references (REF_EXPR) and property accesses (dot/bracket) are valid LHS forms; anything else reaches the switch's default arm.
Solutions
- Fix the script so the compound-assignment LHS is a plain variable or a property access
- Wrap the value in a variable first instead of assigning to a literal/expression
- If the LHS looks valid, check for parser/engine version regressions and upgrade
Example fix
// before obj.getCounter() += 1; // after let c = obj.getCounter() + 1; obj.setCounter(c);
Defensive patterns
Strategy: validation
Validate before calling
// Ensure compound-assignment LHS is an identifier or member expression before eval
if (!/^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\]]+\])*\s*(\+=|-=|\*=)/.test(code)) {
throw new Error('invalid compound-assignment target');
} Type guard
function isAssignableTarget(lhsNode) {
return lhsNode && ['Identifier','MemberExpression'].includes(lhsNode.type);
} Prevention
- Never write assignments to literals, calls, or arbitrary expressions
- Validate generated/transpiled JS with a parser before executing
- Keep the JS parser and interpreter on matching versions
When it happens
Trigger: Compiling/executing a script where the LHS of `op=` parses as neither a variable reference nor a member access — typically invalid or malformed source such as `1 += 2`, a function call as the target, or a parser bug producing an unexpected node type.
Common situations: Hand-written or generated JS with a literal or call on the left of `=`; a syntax/parse regression feeding unexpected AST nodes into the interpreter.
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 logical-assignment to
- cannot apply post inc/dec to
- cannot apply pre inc/dec to
- cannot get from
- cannot set on
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/d4fba775ce6bec04.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java:387
}
yield compoundRefByName(node, context, operator, rhsNode, trackingNode);
}
case REF_DOT_EXPR, REF_BRACKET_EXPR -> {
AccessSite site = resolveWriteSite(node, context);
if (site == null || site == SHORT_CIRCUIT_SITE || context.isStopped()) yield Terms.UNDEFINED;
Object oldValue = site.privateName != null
? PrivateAccess.get(site.target, site.privateName, context)
: siteRead(site, context);
if (context.isStopped()) yield Terms.UNDEFINED;
Object operand = Interpreter.eval(rhsNode, context);
if (context.isStopped()) yield Terms.UNDEFINED;
Object newValue = applyOperator(oldValue, operator, operand, context);
if (context.isStopped()) yield Terms.UNDEFINED;
if (site.privateName != null) PrivateAccess.set(site.target, site.privateName, newValue, context);
else siteWrite(site, newValue, context, trackingNode);
yield newValue;
}
default -> throw JsErrorException.typeError("cannot apply compound assignment to: " + node);
};
}
/**
* ES2021 logical-assignment (||=, &&=, ??=) with short-circuit semantics.
* The LHS reference is resolved once (target + key are evaluated in spec
* order, so `base[key()] ||= rhs` calls `key()` exactly once); the RHS
* expression is evaluated only when the operator's condition requires it.
*/
static Object logicalCompound(Node node, CoreContext context, TokenType operator, Node rhsNode, Node trackingNode) {
return switch (node.type) {
case REF_EXPR -> {
int slot = node.slot;
Object[] frame;
if (slot >= 0 && (frame = context.frame) != null && frame[slot] != SlotTable.UNDECLARED) {
Object oldValue = frame[slot];
if (oldValue == SlotTable.TDZ) {
throw SlotTable.tdzError(node.getText());View on GitHub (pinned to a22eb90246)