{"record":{"id":"19c846fc260634fc","repo":"elastic/elasticsearch","slug":"cannot-apply-operation-to-type-19c846","errorCode":null,"errorMessage":"Cannot apply [-] operation to type [{}].","messagePattern":"Cannot apply \\[-\\] operation to type \\[(.+?)\\]\\.","errorType":"exception","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java","lineNumber":110,"sourceCode":"\n    private static Object neg(final Object unary) {\n        if (unary instanceof Double) {\n            return -(double) unary;\n        } else if (unary instanceof Long) {\n            return -(long) unary;\n        } else if (unary instanceof Integer) {\n            return -(int) unary;\n        } else if (unary instanceof Float) {\n            return -(float) unary;\n        } else if (unary instanceof Short) {\n            return -(short) unary;\n        } else if (unary instanceof Character) {\n            return -(char) unary;\n        } else if (unary instanceof Byte) {\n            return -(byte) unary;\n        }\n\n        throw new ClassCastException(\"Cannot apply [-] operation to type \" + \"[\" + unary.getClass().getCanonicalName() + \"].\");\n    }\n\n    private static int plus(int v) {\n        return +v;\n    }\n\n    private static long plus(long v) {\n        return +v;\n    }\n\n    private static float plus(float v) {\n        return +v;\n    }\n\n    private static double plus(double v) {\n        return +v;\n    }\n","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L92-L128","documentation":"DefMath.neg(Object) is the catch-all for unary negation on def values. It handles boxed numeric types (Double, Long, Integer, Float, Short, Character, Byte). If the runtime type matches none of these (e.g., BigInteger, BigDecimal, String), the method throws a ClassCastException naming the actual type.","triggerScenarios":"A Painless script applies unary minus to a def variable whose runtime type is not a recognized boxed numeric type. Example: `def x = '42'; def y = -x;` where x is a String.","commonSituations":"Negating a def value that unexpectedly resolved to a String (from a keyword or text field). Processing values from external Java libraries that return BigInteger or BigDecimal.","solutions":["Convert the value to a numeric type before negation: `def y = -(double) x;`","Guard with instanceof to ensure the value is a recognized Number subtype.","Use explicit types instead of def for numeric variables."],"exampleFix":"// before\ndef x = doc['amount'].value;\ndef y = -x;\n\n// after\ndef x = doc['amount'].value;\nif (x instanceof Number) {\n    def y = -(double) x;\n}","handlingStrategy":"type-guard","validationCode":"// Painless: check the value is a recognized Number before negation\ndef x = doc['value'].value;\nif (x instanceof Number) {\n    def y = -(double) x;\n} else {\n    // handle non-numeric case\n}","typeGuard":"// Painless type guard for supported numeric box types\ndef isRecognizedNumber(def value) {\n    return value instanceof Double || value instanceof Long || value instanceof Integer || value instanceof Float || value instanceof Short || value instanceof Character || value instanceof Byte;\n}","tryCatchPattern":null,"preventionTips":["Cast or convert values from String or BigInteger to double/long before arithmetic.","Use explicit types instead of def for variables that participate in arithmetic.","Check instanceof before applying unary operators to def-typed values."],"tags":["painless","def-type","unary","type-mismatch","arithmetic"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}