{"record":{"id":"d5221c7073dbbbdf","repo":"elastic/elasticsearch","slug":"cannot-apply-operator-to-types-and","errorCode":null,"errorMessage":"Cannot apply operator [{}] to types [{}] and [{}]","messagePattern":"Cannot apply operator \\[(.+?)\\] to types \\[(.+?)\\] and \\[(.+?)\\]","errorType":"exception","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java","lineNumber":1168,"sourceCode":"                    throw new AssertionError(e);\n                }\n            }))\n    );\n\n    /** Returns an appropriate method handle for a unary or shift operator, based only on the receiver (LHS) */\n    public static MethodHandle lookupUnary(Class<?> receiverClass, String name) {\n        MethodHandle handle = TYPE_OP_MAPPING.get(promote(unbox(receiverClass))).get(name);\n        if (handle == null) {\n            throw new ClassCastException(\"Cannot apply operator [\" + name + \"] to type [\" + receiverClass + \"]\");\n        }\n        return handle;\n    }\n\n    /** Returns an appropriate method handle for a binary operator, based on promotion of the LHS and RHS arguments */\n    public static MethodHandle lookupBinary(Class<?> classA, Class<?> classB, String name) {\n        MethodHandle handle = TYPE_OP_MAPPING.get(promote(promote(unbox(classA)), promote(unbox(classB)))).get(name);\n        if (handle == null) {\n            throw new ClassCastException(\"Cannot apply operator [\" + name + \"] to types [\" + classA + \"] and [\" + classB + \"]\");\n        }\n        return handle;\n    }\n\n    /** Returns a generic method handle for any operator, that can handle all valid signatures, nulls, corner cases */\n    public static MethodHandle lookupGeneric(String name) {\n        return TYPE_OP_MAPPING.get(Object.class).get(name);\n    }\n\n    /**\n     * Slow dynamic cast: casts {@code returnValue} to the runtime type of {@code lhs}\n     * based upon inspection. If {@code lhs} is null, no cast takes place.\n     * This is used for the generic fallback case of compound assignment.\n     */\n    static Object dynamicReceiverCast(Object returnValue, Object lhs) {\n        if (lhs != null) {\n            return dynamicCast(lhs.getClass(), returnValue);\n        } else {","sourceCodeStart":1150,"sourceCodeEnd":1186,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L1150-L1186","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure both operands are of compatible types for the operator (integers for bitwise, matching numeric types for arithmetic).","Cast operands to int/long before applying bitwise binary operators.","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."],"exampleFix":"// before\ndouble a = 1.0, b = 2.0;\ndouble c = a & b;  // bitwise AND on doubles\n// after\nlong a = 1L, b = 2L;\nlong c = a & b;","handlingStrategy":"validation","validationCode":"// Ensure both operands of a binary bitwise operator are int/long:\n// long a = 1L, b = 2L;\n// long c = a & b; // valid\n// double a = 1.0; double c = a & 2.0; // INVALID","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use matching integral types for bitwise binary operators.","Cast floating-point operands to int/long before bitwise ops.","Rely on explicit types so the compiler rejects invalid combinations early."],"tags":["painless","elasticsearch","type-error","operator-resolution","compile-time"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}