{"record":{"id":"92cca6dcbd38aff0","repo":"elastic/elasticsearch","slug":"cannot-apply-operation-to-type-float-92cca6","errorCode":null,"errorMessage":"Cannot apply [>>] operation to type [float]","messagePattern":"Cannot apply \\[>>\\] operation to type \\[float\\]","errorType":"exception","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java","lineNumber":1024,"sourceCode":"\n    public static Object lsh(Object left, long right) {\n        if (left instanceof Long) {\n            return (long) (left) << right;\n        } else {\n            return intIntegralValue(left) << right;\n        }\n    }\n\n    private static int rsh(int a, long b) {\n        return a >> b;\n    }\n\n    private static long rsh(long a, long b) {\n        return a >> b;\n    }\n\n    private static float rsh(float a, long b) {\n        throw new ClassCastException(\"Cannot apply [>>] operation to type [float]\");\n    }\n\n    private static double rsh(double a, long b) {\n        throw new ClassCastException(\"Cannot apply [>>] operation to type [double]\");\n    }\n\n    private static boolean rsh(boolean a, long b) {\n        throw new ClassCastException(\"Cannot apply [>>] operation to type [boolean]\");\n    }\n\n    public static Object rsh(Object left, long right) {\n        if (left instanceof Long) {\n            return (long) left >> right;\n        } else {\n            return intIntegralValue(left) >> right;\n        }\n    }\n","sourceCodeStart":1006,"sourceCodeEnd":1042,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L1006-L1042","documentation":"Painless throws this ClassCastException at runtime when a right-shift (>>) operator is applied to a value that resolves to a float. DefMath registers overloaded rsh() stubs for every type the compiler must account for (int, long, float, double, boolean), but only int and long actually compute a shift; the float/double/boolean overloads exist solely to surface a clear error for the dynamic (def) code path where the compiler cannot know the type at compile time. Shifts are bitwise operations and have no meaning on IEEE-754 floating point, so the runtime refuses them.","triggerScenarios":"A Painless script declares a variable as def and assigns a float value, then uses >> on it: 'def x = 1.5f; def y = x >> 2;'. At runtime the DefMath.rsh(float, long) stub is invoked through the dynamic dispatch in rsh(Object, long) and throws. Static (typed) float code is rejected at compile time; this specific exception only fires through the def/Object path.","commonSituations":"Scripts that read dynamically-typed fields from documents (e.g. doc['some_field'].value) where the field is mapped as float/scaled_float, followed by an attempt to do bit manipulation. Migrating a script from an integer field to a floating-point field without updating the shift logic. Aggregations or runtime fields using def and assuming numeric fields are integers.","solutions":["Change the shift operand to an integral type before shifting: cast with '(int) x >> 2' or '(long) x >> 2'.","Stop using def for the variable; declare it as int or long so the compiler catches the type mismatch at compile time instead of the user at runtime.","If the source field is genuinely floating-point, replace the shift with an equivalent arithmetic operation (e.g. divide by a power of two) since bitwise shift has no defined meaning on floats."],"exampleFix":"// before\ndef x = doc['weight'].value;  // weight is a float field\ndef y = x >> 2;\n// after\nint x = (int) doc['weight'].value;\nint y = x >> 2;","handlingStrategy":"type-guard","validationCode":"// In Painless, before shifting a def value, narrow it:\n// def x = ...;\n// if (x instanceof Integer || x instanceof Long) { int y = ((Number)x).intValue() >> 2; }","typeGuard":"// Painless has no instanceof-over-def for primitives cleanly, but you can check:\n// def x = doc['f'].value;\n// boolean isIntegral = x instanceof Integer || x instanceof Long || x instanceof Short || x instanceof Byte;","tryCatchPattern":null,"preventionTips":["Avoid def for values used in bitwise operations; declare explicit int/long types.","Validate field mappings before writing shift logic on doc values.","Cast def values to int/long explicitly before any shift operator."],"tags":["painless","elasticsearch","type-error","bitwise","def-typing","runtime"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}