elastic/elasticsearch · error · ClassCastException

Cannot apply [*] operation to types [{}] and [{}].

Error message

Cannot apply [*] operation to types [{}] and [{}].

What it means

DefMath.mul(Object, Object) handles multiplication of def values for Number and Character combinations. If neither operand matches any of the Number or Character branches, the method falls through to a terminal ClassCastException naming both operands' actual types.

Source

Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java:214

                }
            }
        } 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 div(int a, int b) {
        return a / b;
    }

    private static long div(long a, long b) {
        return a / b;
    }

    private static float div(float a, float b) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Cast both operands to compatible numeric types: `def z = (double) x * (double) y;`
  2. Guard with instanceof to ensure both operands are Number or Character before multiplying.
  3. Use explicit types instead of def for arithmetic variables.

Example fix

// before
def x = doc['price'].value;
def y = doc['qty'].value;
def total = x * y;

// after
def x = doc['price'].value;
def y = doc['qty'].value;
if (x instanceof Number && y instanceof Number) {
    def total = (double) x * (double) y;
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Painless: verify both operands are Number or Character before multiplication
def a = doc['val1'].value;
def b = doc['val2'].value;
if (a instanceof Number && b instanceof Number) {
    def result = (double) a * (double) b;
} else {
    // handle incompatible types
}

Type guard

// Painless type guard for multipliable types
def canMultiply(def a, def b) {
    return (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

When it happens

Trigger: A Painless script multiplies two def variables whose runtime types are incompatible with multiplication. Example: `def x = 'hello'; def y = 5; def z = x * y;` where x is a String.

Common situations: Multiplying a def value that resolved to a String (from a text or keyword field) with another value. Processing fields whose type varies across documents, causing runtime types to diverge from expectations.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/4e682556bc531aaa. Report an issue: GitHub.