karatelabs/karate · error · java.lang.RuntimeException

unexpected operator

Error message

unexpected operator: <operator>

What it means

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.

Solutions

  1. Note the operator in the message; rewrite the statement using an explicit binary form (x = x op y) to avoid the unsupported compound path.
  2. Upgrade Karate to a version whose evaluator supports the operator.
  3. If reproducible with a plain operator like +=, report it as a bug with a minimal reproducing script.

Example fix

// before (script)
x >>>= 2; // unexpected operator: >>>=
// after
x = x >>> 2;
Defensive patterns

Strategy: validation

Validate before calling

// Only use compound operators known to be supported: += -= *= /= %= <<= >>= >>>= &= |= ^= **=
// and logical: ||= &&= ??=
if (opToken === '>>>=') rewriteAs('x = x >>> 2');

Type guard

function isSupportedCompoundOp(tok) {
  return ['+=','-=','*=','/=','%=','<<=','>>=','>>>=','&=','|=','^=','||=','&&=','??='].includes(tok);
}

Try / catch

try {
    return karate.eval(script);
} catch (RuntimeException e) {
    if (e.getMessage().contains("unexpected operator")) {
        throw new IllegalStateException("script uses an unsupported compound operator", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/582cad83ea744bdf. Report an issue: GitHub.

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java:1352

    }

    //=== Helper methods ===

    private static Object applyOperator(Object oldValue, TokenType operator, Object operand, CoreContext context) {
        return switch (operator) {
            case PLUS_EQ -> Terms.add(oldValue, operand, context);
            case MINUS_EQ -> Terms.min(oldValue, operand, context);
            case STAR_EQ -> Terms.mul(oldValue, operand, context);
            case SLASH_EQ -> Terms.div(oldValue, operand, context);
            case PERCENT_EQ -> Terms.mod(oldValue, operand, context);
            case STAR_STAR_EQ -> Terms.exp(oldValue, operand, context);
            case GT_GT_EQ -> Terms.bitShiftRight(oldValue, operand, context);
            case LT_LT_EQ -> Terms.bitShiftLeft(oldValue, operand, context);
            case GT_GT_GT_EQ -> Terms.bitShiftRightUnsigned(oldValue, operand, context);
            case AMP_EQ -> Terms.bitAnd(oldValue, operand, context);
            case PIPE_EQ -> Terms.bitOr(oldValue, operand, context);
            case CARET_EQ -> Terms.bitXor(oldValue, operand, context);
            default -> throw new RuntimeException("unexpected operator: " + operator);
        };
    }

    private static boolean isFound(Object result) {
        return result != null && result != Terms.UNDEFINED;
    }

    /** Walks the prototype chain looking for an accessor slot at
     *  {@code name}. Returns the first {@link AccessorSlot} found, or
     *  {@code null} (no accessor in chain — write proceeds as a normal
     *  data put on the receiver). Stops at the first own slot at each
     *  level, even if it's a data slot — matches spec
     *  OrdinarySetWithOwnDescriptor semantics. */
    private static AccessorSlot findAccessorInChain(ObjectLike obj, String name) {
        ObjectLike current = obj;
        while (current != null) {
            PropertySlot s = ownSlot(current, name);
            if (s instanceof AccessorSlot acc) return acc;

View on GitHub (pinned to a22eb90246)