elastic/elasticsearch · error · ClassCastException

Cannot apply operator [{}] to types [{}] and [{}]

Error message

Cannot apply operator [{}] to types [{}] and [{}]

What it means

DefMath.lookupBinary throws this ClassCastException at compile/link time when no method handle exists in TYPE_OP_MAPPING for the binary-promoted pair of operand types and the requested operator. The table is keyed by the single promoted result type of both operands (boolean, int, long, float, double, Object); if the promoted type has no entry for the operator name, the handle is null and this error fires. This is the typed-path counterpart of the throwing DefMath stubs.

Source

Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:1168

                    throw new AssertionError(e);
                }
            }))
    );

    /** Returns an appropriate method handle for a unary or shift operator, based only on the receiver (LHS) */
    public static MethodHandle lookupUnary(Class<?> receiverClass, String name) {
        MethodHandle handle = TYPE_OP_MAPPING.get(promote(unbox(receiverClass))).get(name);
        if (handle == null) {
            throw new ClassCastException("Cannot apply operator [" + name + "] to type [" + receiverClass + "]");
        }
        return handle;
    }

    /** Returns an appropriate method handle for a binary operator, based on promotion of the LHS and RHS arguments */
    public static MethodHandle lookupBinary(Class<?> classA, Class<?> classB, String name) {
        MethodHandle handle = TYPE_OP_MAPPING.get(promote(promote(unbox(classA)), promote(unbox(classB)))).get(name);
        if (handle == null) {
            throw new ClassCastException("Cannot apply operator [" + name + "] to types [" + classA + "] and [" + classB + "]");
        }
        return handle;
    }

    /** Returns a generic method handle for any operator, that can handle all valid signatures, nulls, corner cases */
    public static MethodHandle lookupGeneric(String name) {
        return TYPE_OP_MAPPING.get(Object.class).get(name);
    }

    /**
     * Slow dynamic cast: casts {@code returnValue} to the runtime type of {@code lhs}
     * based upon inspection. If {@code lhs} is null, no cast takes place.
     * This is used for the generic fallback case of compound assignment.
     */
    static Object dynamicReceiverCast(Object returnValue, Object lhs) {
        if (lhs != null) {
            return dynamicCast(lhs.getClass(), returnValue);
        } else {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Ensure both operands are of compatible types for the operator (integers for bitwise, matching numeric types for arithmetic).
  2. Cast operands to int/long before applying bitwise binary operators.
  3. If the error is unexpected for valid code, inspect TYPE_OP_MAPPING registration and confirm the operator name string passed by the compiler matches a registered key.

Example fix

// before
double a = 1.0, b = 2.0;
double c = a & b;  // bitwise AND on doubles
// after
long a = 1L, b = 2L;
long c = a & b;
Defensive patterns

Strategy: validation

Validate before calling

// Ensure both operands of a binary bitwise operator are int/long:
// long a = 1L, b = 2L;
// long c = a & b; // valid
// double a = 1.0; double c = a & 2.0; // INVALID

Prevention

When it happens

Trigger: Compiling a Painless script where a binary operator (arithmetic, comparison, or bitwise) is applied to two typed operands whose promoted combination has no registered handle for that operator. For example, applying a bitwise AND/OR/XOR to two floats or doubles — the promotion yields double, and the double entry may lack an 'and'/'or'/'xor' handle.

Common situations: Scripts applying bitwise binary operators to floating-point typed values. Mixing boolean with numeric operands under an operator that requires both sides to match. Compiler or whitelist changes that removed an operator registration for a type.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/d5221c7073dbbbdf. Report an issue: GitHub.