{"record":{"id":"582cad83ea744bdf","repo":"karatelabs/karate","slug":"unexpected-operator-operator","errorCode":null,"errorMessage":"unexpected operator: <operator>","messagePattern":"unexpected operator: <operator>","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java","lineNumber":1352,"sourceCode":"    }\n\n    //=== Helper methods ===\n\n    private static Object applyOperator(Object oldValue, TokenType operator, Object operand, CoreContext context) {\n        return switch (operator) {\n            case PLUS_EQ -> Terms.add(oldValue, operand, context);\n            case MINUS_EQ -> Terms.min(oldValue, operand, context);\n            case STAR_EQ -> Terms.mul(oldValue, operand, context);\n            case SLASH_EQ -> Terms.div(oldValue, operand, context);\n            case PERCENT_EQ -> Terms.mod(oldValue, operand, context);\n            case STAR_STAR_EQ -> Terms.exp(oldValue, operand, context);\n            case GT_GT_EQ -> Terms.bitShiftRight(oldValue, operand, context);\n            case LT_LT_EQ -> Terms.bitShiftLeft(oldValue, operand, context);\n            case GT_GT_GT_EQ -> Terms.bitShiftRightUnsigned(oldValue, operand, context);\n            case AMP_EQ -> Terms.bitAnd(oldValue, operand, context);\n            case PIPE_EQ -> Terms.bitOr(oldValue, operand, context);\n            case CARET_EQ -> Terms.bitXor(oldValue, operand, context);\n            default -> throw new RuntimeException(\"unexpected operator: \" + operator);\n        };\n    }\n\n    private static boolean isFound(Object result) {\n        return result != null && result != Terms.UNDEFINED;\n    }\n\n    /** Walks the prototype chain looking for an accessor slot at\n     *  {@code name}. Returns the first {@link AccessorSlot} found, or\n     *  {@code null} (no accessor in chain — write proceeds as a normal\n     *  data put on the receiver). Stops at the first own slot at each\n     *  level, even if it's a data slot — matches spec\n     *  OrdinarySetWithOwnDescriptor semantics. */\n    private static AccessorSlot findAccessorInChain(ObjectLike obj, String name) {\n        ObjectLike current = obj;\n        while (current != null) {\n            PropertySlot s = ownSlot(current, name);\n            if (s instanceof AccessorSlot acc) return acc;","sourceCodeStart":1334,"sourceCodeEnd":1370,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java#L1334-L1370","documentation":"PropertyAccess's compound-assignment evaluator applies numeric/bitwise compound operators (+=, <<=, >>>=, &=, |=, ^=, etc.) via a switch; the default branch throws \"unexpected operator\" when an operator token reaches this switch that it does not handle. Like shouldLogicalAssign, this is an internal invariant guard against a dispatch/grammar mismatch.","triggerScenarios":"A compound-assignment expression whose operator is not among the implemented arithmetic/bitwise assignment tokens reaches the switch — a parser/evaluator inconsistency, e.g. a newly added operator token unsupported in evaluation.","commonSituations":"Rare in normal use; seen with a library version where the grammar accepts an operator the evaluator does not implement, or corrupted/generated scripts containing unusual assignment tokens.","solutions":["Note the operator in the message; rewrite the statement using an explicit binary form (x = x op y) to avoid the unsupported compound path.","Upgrade Karate to a version whose evaluator supports the operator.","If reproducible with a plain operator like +=, report it as a bug with a minimal reproducing script."],"exampleFix":"// before (script)\nx >>>= 2; // unexpected operator: >>>=\n// after\nx = x >>> 2;","handlingStrategy":"validation","validationCode":"// Only use compound operators known to be supported: += -= *= /= %= <<= >>= >>>= &= |= ^= **=\n// and logical: ||= &&= ??=\nif (opToken === '>>>=') rewriteAs('x = x >>> 2');","typeGuard":"function isSupportedCompoundOp(tok) {\n  return ['+=','-=','*=','/=','%=','<<=','>>=','>>>=','&=','|=','^=','||=','&&=','??='].includes(tok);\n}","tryCatchPattern":"try {\n    return karate.eval(script);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"unexpected operator\")) {\n        throw new IllegalStateException(\"script uses an unsupported compound operator\", e);\n    }\n    throw e;\n}","preventionTips":["Use only common compound-assignment operators in scripts.","Upgrade Karate if a documented operator throws here — indicates version skew.","Prefer explicit binary assignment (x = x op y) for exotic operators."],"tags":["javascript","parser","internal-invariant","compound-assignment"],"backgroundTag":"internal-invariant-violation","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}