elastic/elasticsearch · error · ClassCastException
Cannot apply not [~] to type [double]
Error message
Cannot apply not [~] to type [double]
What it means
The bitwise NOT operator (~) is only defined for integral types. When DefMath receives a def operand whose runtime type is Double, the double overload throws a ClassCastException immediately because bitwise complement has no defined result on IEEE 754 double-precision values.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:48
@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) {
return ~(Character) unary;
} else if (unary instanceof Byte) {
return ~(Byte) unary;
}View on GitHub (pinned to db6a809a66)
Solutions
- Cast the operand to an integral type: `def y = ~(long) x;`
- Declare the variable as int or long instead of def.
- Guard with instanceof to branch on integral vs floating types.
Example fix
// before def x = doc['ratio'].value; def y = ~x; // after def x = (long) doc['ratio'].value; def y = ~x;
Defensive patterns
Strategy: type-guard
Validate before calling
// Painless: cast to long before applying ~ on a double-derived value
def x = doc['value'].value;
if (x instanceof Double) {
def y = ~(long) x;
} else if (x instanceof Long || x instanceof Integer) {
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
- Declare variables intended for bitwise operations as int or long, not def.
- Cast floating-point values to long or int before applying the ~ operator.
- Use the explicit type system so the compiler rejects ~ on double-typed variables.
When it happens
Trigger: A Painless script applies ~ to a def variable holding a Double at runtime. Example: `def x = 3.14; def y = ~x;`
Common situations: Applying bitwise NOT to a computed or document-derived floating-point value. Default numeric literals in Painless def mode resolving to Double when mixed with fractional values.
Related errors
- Cannot apply not [~] to type [float]
- 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/9bb4705a772605f2.
Report an issue: GitHub.