{"record":{"id":"30cb21d05bd4b530","repo":"elastic/elasticsearch","slug":"cannot-apply-operation-to-type-boolean-30cb21","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":815,"sourceCode":"\n    private static boolean gte(int a, int b) {\n        return a >= b;\n    }\n\n    private static boolean gte(long a, long b) {\n        return a >= b;\n    }\n\n    private static boolean gte(float a, float b) {\n        return a >= b;\n    }\n\n    private static boolean gte(double a, double b) {\n        return a >= b;\n    }\n\n    private static boolean gte(boolean a, boolean b) {\n        throw new ClassCastException(\"Cannot apply [>=] operation to type [boolean]\");\n    }\n\n    private static boolean gte(Object left, Object right) {\n        if (left instanceof Number) {\n            if (right instanceof Number) {\n                if (left instanceof Double || right instanceof Double) {\n                    return ((Number) left).doubleValue() >= ((Number) right).doubleValue();\n                } else if (left instanceof Float || right instanceof Float) {\n                    return ((Number) left).floatValue() >= ((Number) right).floatValue();\n                } else if (left instanceof Long || right instanceof Long) {\n                    return ((Number) left).longValue() >= ((Number) right).longValue();\n                } else {\n                    return ((Number) left).intValue() >= ((Number) right).intValue();\n                }\n            } else if (right instanceof Character) {\n                if (left instanceof Double) {\n                    return ((Number) left).doubleValue() >= (char) right;\n                } else if (left instanceof Long) {","sourceCodeStart":797,"sourceCodeEnd":833,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L797-L833","documentation":"Thrown by DefMath.gte(boolean, boolean) which unconditionally throws. When both operands are statically typed boolean, binary promotion yields boolean.class and the compiler selects this overload. Greater-than-or-equal is undefined for booleans in Painless's operator table.","triggerScenarios":"A Painless script applies the >= operator to two operands both statically typed as boolean. The promote() method maps (boolean, boolean) to boolean.class, dispatching to gte(boolean, boolean).","commonSituations":"Using >= on boolean flags in a script_score or runtime field; attempting to establish a boolean ordering or hierarchy; refactored code that previously used numeric fields but was changed to boolean; filter or condition logic mistakenly using >= instead of == on boolean fields.","solutions":["Use == or != for boolean comparisons instead of >=","Convert booleans to integers if ordering semantics are needed","Re-examine the data model: if ordering matters, use an integer or enum-like numeric field"],"exampleFix":"// before\nboolean vip = doc['is_vip'].value;\nboolean elite = doc['is_elite'].value;\nboolean atLeast = vip >= elite;\n\n// after\nint vipLevel = doc['is_vip'].value ? 1 : 0;\nint eliteLevel = doc['is_elite'].value ? 1 : 0;\nboolean atLeast = vipLevel >= eliteLevel;","handlingStrategy":"type-guard","validationCode":"// Convert booleans to integers before using >=\nboolean a = doc['is_valid'].value;\nboolean b = doc['is_checked'].value;\nint ia = a ? 1 : 0;\nint ib = b ? 1 : 0;\nreturn ia >= ib;","typeGuard":"// Reject boolean before relational comparison\nboolean isComparable(Object v) {\n  return v instanceof Number || v instanceof Character;\n}","tryCatchPattern":null,"preventionTips":["Use == or != for boolean operands, never >= or >","Convert booleans to integers if ordering is genuinely required","Audit refactored scripts where numeric fields became boolean","Declare explicit types to catch mismatches at compile time"],"tags":["painless","elasticsearch","boolean","type-error","comparison","runtime","greater-than-equal"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}