{"record":{"id":"c45850bb6487f247","repo":"elastic/elasticsearch","slug":"cannot-apply-operation-to-type-boolean-c45850","errorCode":null,"errorMessage":"Cannot apply [>>] operation to type [boolean]","messagePattern":"Cannot apply \\[>>\\] operation to type \\[boolean\\]","errorType":"exception","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java","lineNumber":1032,"sourceCode":"\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\n    private static long ush(long a, long b) {\n        return a >>> b;\n    }\n","sourceCodeStart":1014,"sourceCodeEnd":1050,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L1014-L1050","documentation":"Painless throws this ClassCastException at runtime when a right-shift (>>) is applied to a boolean value through the def/dynamic path. DefMath.rsh(boolean, long) is a stub that always throws; booleans are not numeric and cannot participate in bitwise shift. The stub exists so the dynamic dispatcher has a method handle for every promoted type, yielding a clear message rather than a NoSuchMethodException.","triggerScenarios":"A def-typed variable that holds a boolean at runtime is shifted: 'def x = true; def y = x >> 1;'. Also occurs when a doc field is boolean-typed and the script attempts bit operations on it.","commonSituations":"Scripts that operate generically over def values without checking the runtime type, or that assume a flag field (0/1) is stored as an integer when it is actually boolean. Logic ported from dynamically-typed languages that treat booleans as 1/0.","solutions":["Convert the boolean to an integer explicitly before shifting: '(x ? 1 : 0) >> 1'.","Use a typed declaration (int/long) and assign a numeric value so the compiler rejects the boolean assignment early.","Reconsider the logic; shifting a boolean is almost always a sign of a type confusion bug."],"exampleFix":"// before\ndef x = doc['active'].value;  // boolean field\ndef y = x >> 1;\n// after\nint x = doc['active'].value ? 1 : 0;\nint y = x >> 1;","handlingStrategy":"type-guard","validationCode":"// Convert boolean to int before any bitwise op:\n// def x = doc['active'].value;\n// int n = (x instanceof Boolean) ? (((Boolean)x) ? 1 : 0) : ((Number)x).intValue();\n// int y = n >> 1;","typeGuard":"// boolean isBool = x instanceof Boolean;","tryCatchPattern":null,"preventionTips":["Check field mappings; boolean fields need explicit conversion before bit operations.","Do not assume def values are numeric.","Prefer typed declarations for fields with known types."],"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-12T13:17:24.610Z"}