elastic/elasticsearch · error · ClassCastException
Cannot convert [{}] to an integral value.
Error message
Cannot convert [{}] to an integral value. What it means
Thrown by DefMath.longIntegralValue(Object) when the object is not one of Long, Integer, Short, Byte, or Character. This helper is called by the Object overload of bitwise operators (&, ^, |) when at least one operand is a Long, requiring both operands to be converted to long. Float, Double, Boolean, String, and other types are rejected because bitwise operations are only defined for integral types in Java semantics.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:878
+ left.getClass().getCanonicalName()
+ "] and ["
+ right.getClass().getCanonicalName()
+ "]."
);
}
// helper methods to convert an integral according to numeric promotion
// this is used by the generic code for bitwise and shift operators
private static long longIntegralValue(Object o) {
if (o instanceof Long) {
return (long) o;
} else if (o instanceof Integer || o instanceof Short || o instanceof Byte) {
return ((Number) o).longValue();
} else if (o instanceof Character) {
return (char) o;
} else {
throw new ClassCastException("Cannot convert [" + o.getClass().getCanonicalName() + "] to an integral value.");
}
}
private static int intIntegralValue(Object o) {
if (o instanceof Integer || o instanceof Short || o instanceof Byte) {
return ((Number) o).intValue();
} else if (o instanceof Character) {
return (char) o;
} else {
throw new ClassCastException("Cannot convert [" + o.getClass().getCanonicalName() + "] to an integral value.");
}
}
// bitwise operators: valid only for integral types
private static int and(int a, int b) {
return a & b;
}View on GitHub (pinned to db6a809a66)
Solutions
- Ensure both operands are integral types (int, long) before applying bitwise operators
- Cast explicitly: longIntegralValue-compatible types only — use ((Number)x).longValue() after checking the type is not Float/Double
- Use explicit long types instead of def for both operands
- Separate the logic: extract integral values into typed variables before bitwise operations
Example fix
// before def flags = doc['bitmask'].value; // Long def factor = params['factor']; // Double def result = flags & factor; // after long flags = doc['bitmask'].value; long factor = (long)(double) params['factor']; long result = flags & factor;
Defensive patterns
Strategy: validation
Validate before calling
// Before bitwise on def values, verify both are integral
def a = doc['mask'].value;
def b = params['bits'];
if (a instanceof Long && b instanceof Long) {
return (long) a & (long) b;
} else if ((a instanceof Integer || a instanceof Long) &&
(b instanceof Integer || b instanceof Long)) {
return ((Number) a).intValue() & ((Number) b).intValue();
}
throw new IllegalArgumentException('Bitwise operands must be integral'); Type guard
// Check if a def value is safe for long bitwise operations
boolean isLongIntegral(def v) {
return v instanceof Long || v instanceof Integer ||
v instanceof Short || v instanceof Byte ||
v instanceof Character;
} Prevention
- Never apply bitwise operators to def variables holding Float or Double values
- Use explicit long or int types for variables involved in bitwise operations
- Verify that params passed from JSON are integers, not doubles (JSON numbers default to double in some parsers)
- Cast floating-point values to long/int explicitly before bitwise operations
When it happens
Trigger: A Painless script applies a bitwise operator (&, ^, |) to two def-typed values where one operand evaluates to Long at runtime and the other evaluates to Float, Double, Boolean, String, or another non-integral type. The and/xor/or(Object, Object) overload enters the 'left instanceof Long || right instanceof Long' branch and calls longIntegralValue on both operands.
Common situations: def variable holding a float/double value used in a bitwise mask operation; mixing a Long bitmask constant with a floating-point def field; def variable from params that was passed as a Double from JSON; bitwise logic on a field that was dynamically typed as float in the mapping.
Related errors
- Cannot apply [-] operation to types [{}] and [{}].
- Cannot apply [<] operation to types [{}] and [{}].
- Cannot apply [<=] operation to types [{}] and [{}].
- Cannot apply [>] operation to types [{}] and [{}].
- Cannot apply [&] operation to type [float]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/b002f34812fcfc08.
Report an issue: GitHub.