{"record":{"id":"f6e9784e7609c6bc","repo":"elastic/elasticsearch","slug":"cannot-apply-operation-to-type-boolean-f6e978","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":677,"sourceCode":"\n    private static boolean lte(int a, int b) {\n        return a <= b;\n    }\n\n    private static boolean lte(long a, long b) {\n        return a <= b;\n    }\n\n    private static boolean lte(float a, float b) {\n        return a <= b;\n    }\n\n    private static boolean lte(double a, double b) {\n        return a <= b;\n    }\n\n    private static boolean lte(boolean a, boolean b) {\n        throw new ClassCastException(\"Cannot apply [<=] operation to type [boolean]\");\n    }\n\n    private static boolean lte(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":659,"sourceCodeEnd":695,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L659-L695","documentation":"Thrown by DefMath.lte(boolean, boolean) which unconditionally throws. When both operands are statically typed boolean, the compiler's promote() method yields boolean.class and dispatches to this overload. Less-than-or-equal has no meaningful semantics for booleans, so the overload always fails.","triggerScenarios":"A Painless script applies the <= operator to two operands both statically typed as boolean. Binary promotion selects boolean.class, and the lte(boolean, boolean) overload is called.","commonSituations":"Using <= on boolean flags or toggles; attempting range logic on a boolean field; refactoring numeric comparison code to operate on boolean fields without changing the operator; aggregating or sorting by a boolean field with <= logic.","solutions":["Replace <= with equality (==) or inequality (!=) for boolean operands","Convert booleans to integers (0/1) before applying <= if you need ordering semantics","Change the field mapping from boolean to a numeric type if ordering is a genuine requirement"],"exampleFix":"// before\nboolean a = doc['enabled'].value;\nboolean b = doc['locked'].value;\nboolean result = a <= b;\n\n// after\nint ia = doc['enabled'].value ? 1 : 0;\nint ib = doc['locked'].value ? 1 : 0;\nboolean result = ia <= ib;","handlingStrategy":"type-guard","validationCode":"// Before using <= on booleans, convert to integers\nboolean a = doc['flag_a'].value;\nboolean b = doc['flag_b'].value;\nint ia = a ? 1 : 0;\nint ib = b ? 1 : 0;\nreturn ia <= ib;","typeGuard":"// Verify the value is not boolean before relational comparison\nboolean isNotBoolean(Object v) {\n  return !(v instanceof Boolean);\n}","tryCatchPattern":null,"preventionTips":["Use == or != for boolean comparisons, not <= or >=","Convert booleans to integers (0/1) if ordering semantics are genuinely needed","Review scripts that were refactored from numeric fields to boolean fields","Declare explicit types instead of def to get compile-time type checking"],"tags":["painless","elasticsearch","boolean","type-error","comparison","runtime","less-than-equal"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}