elastic/elasticsearch · error · ClassCastException
Cannot apply not [~] to type [float]
Error message
Cannot apply not [~] to type [float]
What it means
The bitwise NOT operator (~) is only defined for integral types (int, long, short, char, byte). DefMath routes def-typed operands to type-specific overloads; when the runtime value is a float, the float overload unconditionally throws a ClassCastException because there is no meaningful bitwise complement for floating-point values.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:44
* {@code int,long,float,double,boolean,Object}. Operators can throw exceptions if
* the type is illegal. The {@code Object} type must be a "generic" handler that
* handles all legal types: it must be convertible to every possible legal signature.
*/
@SuppressWarnings("unused")
public class DefMath {
// Unary not: only applicable to integral types
private static int not(int v) {
return ~v;
}
private static long not(long v) {
return ~v;
}
private static float not(float v) {
throw new ClassCastException("Cannot apply not [~] to type [float]");
}
private static double not(double v) {
throw new ClassCastException("Cannot apply not [~] to type [double]");
}
private static boolean not(boolean v) {
throw new ClassCastException("Cannot apply not [~] to type [boolean]");
}
private static Object not(Object unary) {
if (unary instanceof Long) {
return ~(Long) unary;
} else if (unary instanceof Integer) {
return ~(Integer) unary;
} else if (unary instanceof Short) {
return ~(Short) unary;
} else if (unary instanceof Character) {View on GitHub (pinned to db6a809a66)
Solutions
- Ensure the operand is an integral type before applying ~.
- Cast the def value to int or long explicitly: `def y = ~(int) x;`
- Use an explicit type declaration (int, long) instead of def for the variable.
Example fix
// before def x = doc['score'].value; def y = ~x; // after def x = (int) doc['score'].value; def y = ~x;
Defensive patterns
Strategy: type-guard
Validate before calling
// Painless: ensure the value is integral before applying ~
def x = doc['value'].value;
if (x instanceof Integer || x instanceof Long) {
def y = ~x;
} Type guard
// Painless type guard for integral types
def isIntegral(def value) {
return value instanceof Integer || value instanceof Long || value instanceof Short || value instanceof Byte || value instanceof Character;
} Prevention
- Use the logical NOT (!) for boolean values; reserve ~ strictly for integer types.
- Declare variables intended for bitwise operations as int or long, not def or float/double.
- Cast to int or long explicitly before ~ if the source value may be floating-point.
When it happens
Trigger: A Painless script applies the ~ operator to a def variable whose runtime value is a Float. Example: `def x = 1.5f; def y = ~x;`
Common situations: A script receives a floating-point value from a document field or computation but applies a bitwise operation intended for integers. Mixing def-typed numeric values where the type is inferred from runtime data.
Related errors
- Cannot apply not [~] to type [double]
- Cannot apply [~] operation to type [{}].
- Cannot apply not [~] to type [boolean]
- Cannot apply [-] operation to type [boolean]
- Cannot apply [-] operation to type [{}].
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/cb8baf2c9b349498.
Report an issue: GitHub.