{"record":{"id":"76c72af8da96dcc4","repo":"karatelabs/karate","slug":"cannot-apply-post-inc-dec-to-node","errorCode":null,"errorMessage":"cannot apply post inc/dec to: ${node}","messagePattern":"cannot apply post inc/dec to: (.+?)","errorType":"exception","errorClass":"JsErrorException (typeError)","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java","lineNumber":563,"sourceCode":"                    yield oldValue;\n                }\n                yield incDecRefByName(node, context, isIncrement, false);\n            }\n            case REF_DOT_EXPR, REF_BRACKET_EXPR -> {\n                AccessSite site = resolveWriteSite(node, context);\n                if (site == null || site == SHORT_CIRCUIT_SITE) yield Terms.UNDEFINED;\n                if (site.privateName != null) yield privateIncDec(site, isIncrement, false, context);\n                if (site.receiver != null) yield superIncDec(site, isIncrement, false, context);\n                yield site.isIndex\n                        ? postIncDecByIndex(site.target, site.key, isIncrement, context)\n                        : postIncDecByName(site.target, (String) site.key, isIncrement, context);\n            }\n            case LIT_EXPR -> {\n                // Handle literals like (x)++ where x is wrapped\n                Object oldValue = Interpreter.eval(node, context);\n                yield oldValue; // Can't actually modify a literal result\n            }\n            default -> throw JsErrorException.typeError(\"cannot apply post inc/dec to: \" + node);\n        };\n    }\n\n    /**\n     * Pre-increment/decrement: updates variable, returns new value.\n     */\n    static Object preIncDec(Node node, CoreContext context, boolean isIncrement) {\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());\n                    }\n                    Object step = Terms.incDecStep(oldValue);\n                    Object newValue = isIncrement ? Terms.add(oldValue, step, context) : Terms.min(oldValue, step, context);","sourceCodeStart":545,"sourceCodeEnd":581,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java#L545-L581","documentation":"A TypeError thrown when a post-increment/decrement operator is applied to a node type that is not a variable reference or property access. Literal and other unexpected node shapes reach the switch's default arm; literals themselves are handled as no-ops ((x)++ returns the value unchanged), so this error signals a truly unsupported LHS form.","triggerScenarios":"Executing `expr++` where expr parses as neither REF_EXPR, REF_DOT_EXPR, REF_BRACKET_EXPR, nor LIT_EXPR — e.g. `(a, b)++`, assignment to a call, or a malformed AST from a parser bug.","commonSituations":"Generated or transpiled code emitting invalid increment targets; hand-written JS like `foo()++`; engine version mismatch between parser and interpreter.","solutions":["Rewrite so the increment target is a variable or property: `obj.count++`","Assign the expression result to a variable first, then increment the variable","Check for parser/interpreter version mismatches if the source looks valid"],"exampleFix":"// before\n(a + b)++;\n// after\nlet s = a + b;\ns++;","handlingStrategy":"validation","validationCode":"// Reject increment/decrement on non-assignable expressions\nif (/\\+\\+\\s*[^A-Za-z_$([]|--[^A-Za-z_$([]/.test(code)) { /* flag invalid target */ }","typeGuard":"function isIncDecTarget(node) {\n  return node && ['Identifier','MemberExpression'].includes(node.type);\n}","tryCatchPattern":null,"preventionTips":["Never write `expr++` where expr is a call, literal, or parenthesized binary expression","Parse generated code and validate increment targets","Keep parser and interpreter versions aligned"],"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"}