{"record":{"id":"267c0b2223d83be1","repo":"elastic/elasticsearch","slug":"cannot-apply-operation-to-type-double-267c0b","errorCode":null,"errorMessage":"Cannot apply [>>] operation to type [double]","messagePattern":"Cannot apply \\[>>\\] operation to type \\[double\\]","errorType":"exception","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java","lineNumber":1028,"sourceCode":"        } 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\n    private static int ush(int a, long b) {\n        return a >>> b;\n    }\n","sourceCodeStart":1010,"sourceCodeEnd":1046,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L1010-L1046","documentation":"Painless throws this ClassCastException at runtime when a right-shift (>>) operator is applied to a value that resolves to a double. As with the float stub, DefMath.rsh(double, long) exists only so the dynamic (def) dispatch path produces a readable error; double is an IEEE-754 floating-point type and bitwise shift is undefined for it. Only int and long overloads of rsh actually perform the operation.","triggerScenarios":"A Painless script uses def and the operand is a double at runtime: 'def x = 3.14; def y = x >> 1;'. This routes through rsh(Object, long) which, after numeric promotion, hits the double stub. Commonly seen when doc field values default to double or when arithmetic produces a double result that is then shifted.","commonSituations":"Doc fields mapped as double, double_valued expressions, or computed values from division that widen to double. Scripts ported from languages that silently truncate floats before shifting. Runtime-mapped fields that return double.","solutions":["Cast the operand to int or long before the shift: '(long) x >> 1'.","Declare the variable with an explicit integral type instead of def to force compile-time rejection.","Re-examine the logic: if the value is genuinely continuous, a bitwise shift is likely a bug; replace with multiplication/division by a power of two."],"exampleFix":"// before\ndef x = doc['score'].value;  // double field\ndef y = x >> 3;\n// after\nlong x = (long) doc['score'].value;\nlong y = x >> 3;","handlingStrategy":"type-guard","validationCode":"// Cast before shifting to guarantee integral dispatch:\n// def x = doc['score'].value;\n// long shifted = ((long) x) >> 1;","typeGuard":"// boolean isIntegral = x instanceof Integer || x instanceof Long || x instanceof Short || x instanceof Byte;","tryCatchPattern":null,"preventionTips":["Use explicit long/int declarations for shift operands instead of def.","Cast double-valued def variables to long before shifting.","Audit scripts that mix floating-point fields with bitwise logic."],"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-12T12:31:55.035Z"}