elastic/elasticsearch · error · ClassCastException
Cannot apply [+] operation to types [{}] and [{}].
Error message
Cannot apply [+] operation to types [{}] and [{}]. What it means
DefMath.add(Object, Object) handles binary addition for numeric types, String concatenation (either operand being String), and Character combinations. If neither operand matches any supported branch, the method throws a ClassCastException naming both operands' actual runtime types.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:428
}
}
} else if (left instanceof Character) {
if (right instanceof Number) {
if (right instanceof Double) {
return (char) left + ((Number) right).doubleValue();
} else if (right instanceof Long) {
return (char) left + ((Number) right).longValue();
} else if (right instanceof Float) {
return (char) left + ((Number) right).floatValue();
} else {
return (char) left + ((Number) right).intValue();
}
} else if (right instanceof Character) {
return (char) left + (char) right;
}
}
throw new ClassCastException(
"Cannot apply [+] operation to types "
+ "["
+ left.getClass().getCanonicalName()
+ "] and ["
+ right.getClass().getCanonicalName()
+ "]."
);
}
private static int sub(int a, int b) {
return a - b;
}
private static long sub(long a, long b) {
return a - b;
}
private static float sub(float a, float b) {View on GitHub (pinned to db6a809a66)
Solutions
- Cast operands to compatible types (double/long for arithmetic, String for concatenation).
- Guard with instanceof to verify operands are Number, String, or Character before adding.
- Use explicit types instead of def for arithmetic and string operations.
Example fix
// before
def a = doc['val1'].value;
def b = doc['val2'].value;
def sum = a + b;
// after
def a = doc['val1'].value;
def b = doc['val2'].value;
if (a instanceof Number && b instanceof Number) {
def sum = (double) a + (double) b;
} else {
def sum = String.valueOf(a) + String.valueOf(b);
} Defensive patterns
Strategy: type-guard
Validate before calling
// Painless: verify operands are compatible (Number/String/Character) before addition
def a = doc['val1'].value;
def b = doc['val2'].value;
if (a instanceof Number && b instanceof Number) {
def result = (double) a + (double) b;
} else if (a instanceof String || b instanceof String) {
def result = String.valueOf(a) + String.valueOf(b);
} else {
// incompatible types
} Type guard
// Painless type guard for addable types
def canAdd(def a, def b) {
return (a instanceof String) || (b instanceof String) || (a instanceof Number && b instanceof Number) || (a instanceof Number && b instanceof Character) || (a instanceof Character && b instanceof Number) || (a instanceof Character && b instanceof Character);
} Prevention
- Cast or convert def values to compatible types (double for arithmetic, String for concatenation) before addition.
- Use explicit types instead of def for variables used in additive expressions.
- Check instanceof on both operands to handle all type combinations explicitly.
When it happens
Trigger: A Painless script adds two def variables whose runtime types are incompatible with addition and neither is a String. Example: `def x = new ArrayList(); def y = 5; def z = x + y;` where x is a List (not String, not Number, not Character).
Common situations: Adding a def value that resolved to an unexpected type (List, Map, custom object) from a document field or API call. Processing values from heterogeneous sources where the runtime type is unpredictable.
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 [{}].
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/c8d35c8fc84b1047.
Report an issue: GitHub.