elastic/elasticsearch · error · ClassCastException
Cannot apply [>>] operation to type [double]
Error message
Cannot apply [>>] operation to type [double]
What it means
Painless throws this ClassCastException at runtime when a right-shift (>>) operator is applied to a value that resolves to a double. As with the float stub, DefMath.rsh(double, long) exists only so the dynamic (def) dispatch path produces a readable error; double is an IEEE-754 floating-point type and bitwise shift is undefined for it. Only int and long overloads of rsh actually perform the operation.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:1028
} else {
return intIntegralValue(left) << right;
}
}
private static int rsh(int a, long b) {
return a >> b;
}
private static long rsh(long a, long b) {
return a >> b;
}
private static float rsh(float a, long b) {
throw new ClassCastException("Cannot apply [>>] operation to type [float]");
}
private static double rsh(double a, long b) {
throw new ClassCastException("Cannot apply [>>] operation to type [double]");
}
private static boolean rsh(boolean a, long b) {
throw new ClassCastException("Cannot apply [>>] operation to type [boolean]");
}
public static Object rsh(Object left, long right) {
if (left instanceof Long) {
return (long) left >> right;
} else {
return intIntegralValue(left) >> right;
}
}
private static int ush(int a, long b) {
return a >>> b;
}
View on GitHub (pinned to db6a809a66)
Solutions
- Cast the operand to int or long before the shift: '(long) x >> 1'.
- Declare the variable with an explicit integral type instead of def to force compile-time rejection.
- Re-examine the logic: if the value is genuinely continuous, a bitwise shift is likely a bug; replace with multiplication/division by a power of two.
Example fix
// before def x = doc['score'].value; // double field def y = x >> 3; // after long x = (long) doc['score'].value; long y = x >> 3;
Defensive patterns
Strategy: type-guard
Validate before calling
// Cast before shifting to guarantee integral dispatch: // def x = doc['score'].value; // long shifted = ((long) x) >> 1;
Type guard
// boolean isIntegral = x instanceof Integer || x instanceof Long || x instanceof Short || x instanceof Byte;
Prevention
- Use explicit long/int declarations for shift operands instead of def.
- Cast double-valued def variables to long before shifting.
- Audit scripts that mix floating-point fields with bitwise logic.
When it happens
Trigger: A Painless script uses def and the operand is a double at runtime: 'def x = 3.14; def y = x >> 1;'. This routes through rsh(Object, long) which, after numeric promotion, hits the double stub. Commonly seen when doc field values default to double or when arithmetic produces a double result that is then shifted.
Common situations: Doc fields mapped as double, double_valued expressions, or computed values from division that widen to double. Scripts ported from languages that silently truncate floats before shifting. Runtime-mapped fields that return double.
Related errors
- Cannot apply [>>] operation to type [float]
- Cannot apply [>>] operation to type [boolean]
- Cannot apply [>>>] operation to type [float]
- Cannot apply [>>>] operation to type [double]
- Cannot apply [>>>] operation to type [boolean]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/267c0b2223d83be1.
Report an issue: GitHub.