{"record":{"id":"d4fba775ce6bec04","repo":"karatelabs/karate","slug":"cannot-apply-compound-assignment-to-node","errorCode":null,"errorMessage":"cannot apply compound assignment to: ${node}","messagePattern":"cannot apply compound assignment to: (.+?)","errorType":"exception","errorClass":"JsErrorException (typeError)","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java","lineNumber":387,"sourceCode":"                }\n                yield compoundRefByName(node, context, operator, rhsNode, trackingNode);\n            }\n            case REF_DOT_EXPR, REF_BRACKET_EXPR -> {\n                AccessSite site = resolveWriteSite(node, context);\n                if (site == null || site == SHORT_CIRCUIT_SITE || context.isStopped()) yield Terms.UNDEFINED;\n                Object oldValue = site.privateName != null\n                        ? PrivateAccess.get(site.target, site.privateName, context)\n                        : siteRead(site, context);\n                if (context.isStopped()) yield Terms.UNDEFINED;\n                Object operand = Interpreter.eval(rhsNode, context);\n                if (context.isStopped()) yield Terms.UNDEFINED;\n                Object newValue = applyOperator(oldValue, operator, operand, context);\n                if (context.isStopped()) yield Terms.UNDEFINED;\n                if (site.privateName != null) PrivateAccess.set(site.target, site.privateName, newValue, context);\n                else siteWrite(site, newValue, context, trackingNode);\n                yield newValue;\n            }\n            default -> throw JsErrorException.typeError(\"cannot apply compound assignment to: \" + node);\n        };\n    }\n\n    /**\n     * ES2021 logical-assignment (||=, &&=, ??=) with short-circuit semantics.\n     * The LHS reference is resolved once (target + key are evaluated in spec\n     * order, so `base[key()] ||= rhs` calls `key()` exactly once); the RHS\n     * expression is evaluated only when the operator's condition requires it.\n     */\n    static Object logicalCompound(Node node, CoreContext context, TokenType operator, Node rhsNode, Node trackingNode) {\n                return switch (node.type) {\n            case REF_EXPR -> {\n                int slot = node.slot;\n                Object[] frame;\n                if (slot >= 0 && (frame = context.frame) != null && frame[slot] != SlotTable.UNDECLARED) {\n                    Object oldValue = frame[slot];\n                    if (oldValue == SlotTable.TDZ) {\n                        throw SlotTable.tdzError(node.getText());","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java#L369-L405","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nobj.getCounter() += 1;\n// after\nlet c = obj.getCounter() + 1;\nobj.setCounter(c);","handlingStrategy":"validation","validationCode":"// Ensure compound-assignment LHS is an identifier or member expression before eval\nif (!/^[A-Za-z_$][\\w$]*(\\.[A-Za-z_$][\\w$]*|\\[[^\\]]+\\])*\\s*(\\+=|-=|\\*=)/.test(code)) {\n  throw new Error('invalid compound-assignment target');\n}","typeGuard":"function isAssignableTarget(lhsNode) {\n  return lhsNode && ['Identifier','MemberExpression'].includes(lhsNode.type);\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["javascript","ast","unsupported-lhs"],"backgroundTag":"unsupported-operation","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}