{"record":{"id":"33214bcfaa6aa34f","repo":"elastic/elasticsearch","slug":"cannot-apply-operation-to-types-and-33214b","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":352,"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    // addition: applicable to all numeric types.\n    // additionally, if either type is a string, the other type can be any arbitrary type (including null)\n\n    private static int add(int a, int b) {\n        return a + b;\n    }\n\n    private static long add(long a, long b) {\n        return a + b;","sourceCodeStart":334,"sourceCodeEnd":370,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L334-L370","documentation":"DefMath.rem(Object, Object) handles the remainder operator on def values for Number 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 applies % to two def variables whose runtime types are incompatible with the remainder operation. Example: `def x = 'hello'; def y = 3; def z = x % y;` where x is a String.","commonSituations":"Applying modulo to a def value that resolved to a String from a text or keyword field. Processing fields with heterogeneous types across documents.","solutions":["Cast both operands to compatible numeric types: `def z = (int) x % (int) y;`","Guard with instanceof to verify both are Number or Character.","Use explicit types instead of def for arithmetic variables."],"exampleFix":"// before\ndef n = doc['count'].value;\ndef m = doc['bucket'].value;\ndef r = n % m;\n\n// after\ndef n = doc['count'].value;\ndef m = doc['bucket'].value;\nif (n instanceof Number && m instanceof Number) {\n    def r = (int) n % (int) m;\n}","handlingStrategy":"type-guard","validationCode":"// Painless: verify both operands are Number or Character before modulo\ndef a = doc['val1'].value;\ndef b = doc['val2'].value;\nif (a instanceof Number && b instanceof Number) {\n    def result = (int) a % (int) b;\n}","typeGuard":"// Painless type guard for modulo-compatible types\ndef canMod(def a, def b) {\n    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);\n}","tryCatchPattern":null,"preventionTips":["Cast def values to int or long before applying the % operator.","Use explicit types instead of def for modulo operands.","Check instanceof on both operands to avoid incompatible-type falls-through."],"tags":["painless","def-type","modulo","type-mismatch","arithmetic"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}