elastic/elasticsearch · error · ClassCastException

Cannot apply [+] operation to type [{}].

Error message

Cannot apply [+] operation to type [{}].

What it means

DefMath.plus(Object) is the catch-all for unary plus on def values. It accepts boxed numeric types (Double, Long, Integer, Float, Short, Character, Byte). If the runtime type matches none of these, it throws a ClassCastException naming the actual type.

Source

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

    private static Object plus(final Object unary) {
        if (unary instanceof Double) {
            return +(double) unary;
        } else if (unary instanceof Long) {
            return +(long) unary;
        } else if (unary instanceof Integer) {
            return +(int) unary;
        } else if (unary instanceof Float) {
            return +(float) unary;
        } else if (unary instanceof Short) {
            return +(short) unary;
        } else if (unary instanceof Character) {
            return +(char) unary;
        } else if (unary instanceof Byte) {
            return +(byte) unary;
        }

        throw new ClassCastException("Cannot apply [+] operation to type " + "[" + unary.getClass().getCanonicalName() + "].");
    }

    // multiplication/division/remainder/subtraction: applicable to all integer types

    private static int mul(int a, int b) {
        return a * b;
    }

    private static long mul(long a, long b) {
        return a * b;
    }

    private static float mul(float a, float b) {
        return a * b;
    }

    private static double mul(double a, double b) {
        return a * b;

View on GitHub (pinned to db6a809a66)

Solutions

  1. Convert to a numeric type first: `def y = +(double) x;`
  2. Guard with instanceof to verify the value is a recognized Number.
  3. Use explicit types instead of def.

Example fix

// before
def x = doc['value'].value;
def y = +x;

// after
def x = doc['value'].value;
if (x instanceof Number) {
    def y = +(double) x;
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Painless: check the value is a recognized Number before unary plus
def x = doc['value'].value;
if (x instanceof Number) {
    def y = +(double) x;
}

Type guard

// Painless type guard for supported numeric box types
def isRecognizedNumber(def value) {
    return value instanceof Double || value instanceof Long || value instanceof Integer || value instanceof Float || value instanceof Short || value instanceof Character || value instanceof Byte;
}

Prevention

When it happens

Trigger: A Painless script applies unary + to a def variable whose runtime type is not a recognized boxed numeric type. Example: `def x = new BigInteger('10'); def y = +x;`

Common situations: Applying unary + to a def value that resolved to a String, BigInteger, or BigDecimal from a document field or Java library call.

Related errors


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