{"record":{"id":"c8d35c8fc84b1047","repo":"elastic/elasticsearch","slug":"cannot-apply-operation-to-types-and-c8d35c","errorCode":null,"errorMessage":"Cannot apply [+] operation to types [{}] and [{}].","messagePattern":"Cannot apply \\[\\+\\] operation to types \\[(.+?)\\] and \\[(.+?)\\]\\.","errorType":"exception","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java","lineNumber":428,"sourceCode":"                }\n            }\n        } else if (left instanceof Character) {\n            if (right instanceof Number) {\n                if (right instanceof Double) {\n                    return (char) left + ((Number) right).doubleValue();\n                } else if (right instanceof Long) {\n                    return (char) left + ((Number) right).longValue();\n                } else if (right instanceof Float) {\n                    return (char) left + ((Number) right).floatValue();\n                } else {\n                    return (char) left + ((Number) right).intValue();\n                }\n            } else if (right instanceof Character) {\n                return (char) left + (char) right;\n            }\n        }\n\n        throw new ClassCastException(\n            \"Cannot apply [+] operation to types \"\n                + \"[\"\n                + left.getClass().getCanonicalName()\n                + \"] and [\"\n                + right.getClass().getCanonicalName()\n                + \"].\"\n        );\n    }\n\n    private static int sub(int a, int b) {\n        return a - b;\n    }\n\n    private static long sub(long a, long b) {\n        return a - b;\n    }\n\n    private static float sub(float a, float b) {","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L410-L446","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\ndef a = doc['val1'].value;\ndef b = doc['val2'].value;\ndef sum = a + b;\n\n// after\ndef a = doc['val1'].value;\ndef b = doc['val2'].value;\nif (a instanceof Number && b instanceof Number) {\n    def sum = (double) a + (double) b;\n} else {\n    def sum = String.valueOf(a) + String.valueOf(b);\n}","handlingStrategy":"type-guard","validationCode":"// Painless: verify operands are compatible (Number/String/Character) before addition\ndef a = doc['val1'].value;\ndef b = doc['val2'].value;\nif (a instanceof Number && b instanceof Number) {\n    def result = (double) a + (double) b;\n} else if (a instanceof String || b instanceof String) {\n    def result = String.valueOf(a) + String.valueOf(b);\n} else {\n    // incompatible types\n}","typeGuard":"// Painless type guard for addable types\ndef canAdd(def a, def b) {\n    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);\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["painless","def-type","addition","type-mismatch","arithmetic"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}