elastic/elasticsearch · error · ClassCastException
Cannot apply [<=] operation to types [{}] and [{}].
Error message
Cannot apply [<=] operation to types [{}] and [{}]. What it means
Thrown by DefMath.lte(Object, Object) when the runtime types of both operands do not match any supported less-than-or-equal combination. The Object overload dispatches through instanceof Number and instanceof Character checks; unrecognized type pairs fall through to this ClassCastException. Only triggered with def-typed operands.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:719
}
}
} else if (left instanceof Character) {
if (right instanceof Number) {
if (right instanceof Double) {
return (char) left <= ((Number) right).doubleValue();
} else if (right instanceof Long) {
return (char) left <= ((Number) right).longValue();
} else if (right instanceof Float) {
return (char) left <= ((Number) right).floatValue();
} else {
return (char) left <= ((Number) right).intValue();
}
} else if (right instanceof Character) {
return (char) left <= (char) right;
}
}
throw new ClassCastException(
"Cannot apply [<=] operation to types "
+ "["
+ left.getClass().getCanonicalName()
+ "] and ["
+ right.getClass().getCanonicalName()
+ "]."
);
}
private static boolean gt(int a, int b) {
return a > b;
}
private static boolean gt(long a, long b) {
return a > b;
}
private static boolean gt(float a, float b) {View on GitHub (pinned to db6a809a66)
Solutions
- Use explicit numeric types for both operands to get compile-time type checking
- Add an instanceof Number guard: if (a instanceof Number && b instanceof Number) { return ((Number)a).doubleValue() <= ((Number)b).doubleValue(); }
- Fix the mapping to use a consistent numeric type for the field
- If comparing date strings, parse to long epoch millis first using Long.parseLong() or a date formatter
Example fix
// before def val = doc['price'].value; def cap = params['max']; boolean ok = val <= cap; // after double val = doc['price'].value; double cap = (double) params['max']; boolean ok = val <= cap;
Defensive patterns
Strategy: type-guard
Validate before calling
// Guard def comparison with type checks
def val = doc['score'].value;
def limit = params['cap'];
if (val instanceof Number && limit instanceof Number) {
return ((Number) val).doubleValue() <= ((Number) limit).doubleValue();
}
return false; Type guard
// Check numeric compatibility before <= comparison
boolean bothNumeric(def a, def b) {
return a instanceof Number && b instanceof Number;
} Prevention
- Declare both operands with explicit numeric types instead of def
- Verify index mappings are consistent across all indices involved in the search
- Check for missing/null fields: if (doc['field'].size() == 0) return false;
- Test scripts against representative documents before production deployment
When it happens
Trigger: A Painless script applies <= to two def-typed values where at least one resolves at runtime to a non-numeric, non-character type (String, List, Map, null). The Object overload is invoked and no instanceof branch matches.
Common situations: Field mapped as keyword/text used in a <= threshold check; def variable from an untyped source (params map, _source parsing) compared numerically; heterogeneous documents where field type varies; comparing a date-formatted string against a numeric epoch.
Related errors
- Cannot apply [<] operation to types [{}] and [{}].
- Cannot apply [<=] operation to type [boolean]
- Cannot apply [>] operation to types [{}] and [{}].
- Cannot apply [-] operation to types [{}] and [{}].
- Cannot apply [<] operation to type [boolean]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/37f57f40f9f72fbb.
Report an issue: GitHub.