elastic/elasticsearch · error · ClassCastException
Cannot apply not [~] to type [boolean]
Error message
Cannot apply not [~] to type [boolean]
What it means
The bitwise NOT operator (~) operates on individual bits and has no meaning for boolean values. DefMath's boolean overload for not() throws a ClassCastException when a def variable resolves to Boolean at runtime and ~ is applied.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:52
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;
}
throw new ClassCastException("Cannot apply [~] operation to type " + "[" + unary.getClass().getCanonicalName() + "].");
}
View on GitHub (pinned to db6a809a66)
Solutions
- Use the logical NOT operator (!) instead of bitwise NOT (~) for boolean values.
- If an integer representation is needed, cast to int first: `def y = ~(int) x;`
- Use an explicit boolean type declaration so the compiler rejects ~ at compile time.
Example fix
// before def flag = doc['active'].value; def inverted = ~flag; // after boolean flag = doc['active'].value; boolean inverted = !flag;
Defensive patterns
Strategy: type-guard
Validate before calling
// Painless: use logical NOT (!) for boolean, not bitwise NOT (~)
def x = doc['flag'].value;
if (x instanceof Boolean) {
boolean inverted = !x;
} else if (x instanceof Integer || x instanceof Long) {
def y = ~x;
} Type guard
// Painless type guard distinguishing boolean from integral
def isIntegral(def value) {
return value instanceof Integer || value instanceof Long || value instanceof Short || value instanceof Byte || value instanceof Character;
} Prevention
- Use ! (logical NOT) for boolean values and ~ (bitwise NOT) only for integer types.
- Declare boolean fields as `boolean` not `def` so the compiler catches operator misuse.
- Review operator choice when working with flag fields from documents.
When it happens
Trigger: A Painless script applies ~ to a def variable whose runtime value is a Boolean. Example: `def x = true; def y = ~x;`
Common situations: A script receives a boolean field value from a document (e.g., a flag) and mistakenly applies a bitwise operator instead of a logical operator (!).
Related errors
- Cannot apply not [~] to type [float]
- Cannot apply not [~] to type [double]
- Cannot apply [~] operation to type [{}].
- Cannot apply [-] operation to type [boolean]
- Cannot apply [+] operation to type [boolean]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/4998ca7b5566b4a4.
Report an issue: GitHub.