elastic/elasticsearch · error · ClassCastException

Cannot apply [-] operation to type [boolean]

Error message

Cannot apply [-] operation to type [boolean]

What it means

Unary negation (-) is defined for all numeric types but not for boolean. DefMath's boolean overload for neg() throws a ClassCastException when a def variable resolves to Boolean and the minus sign is applied.

Source

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

    private static int neg(int v) {
        return -v;
    }

    private static long neg(long v) {
        return -v;
    }

    private static float neg(float v) {
        return -v;
    }

    private static double neg(double v) {
        return -v;
    }

    private static boolean neg(boolean v) {
        throw new ClassCastException("Cannot apply [-] operation to type [boolean]");
    }

    private static Object neg(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;
        }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Verify the operand is numeric, not boolean, before negation.
  2. Use an explicit type declaration (int, long, double) instead of def.
  3. Guard with instanceof and branch to handle boolean separately.

Example fix

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

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

Strategy: type-guard

Validate before calling

// Painless: ensure the value is numeric before unary negation
def x = doc['flag'].value;
if (x instanceof Number) {
    def y = -(double) x;
}

Type guard

// Painless type guard for numeric types
def isNumeric(def value) {
    return value instanceof Number;
}

Prevention

When it happens

Trigger: A Painless script applies unary minus to a def variable holding a Boolean at runtime. Example: `def x = true; def y = -x;`

Common situations: A script receives a boolean field and mistakenly applies arithmetic negation. Mixing logical and arithmetic operations on def-typed values without type guards.

Related errors


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