{"record":{"id":"ace9edef70603a8f","repo":"elastic/elasticsearch","slug":"cannot-apply-operation-to-type-boolean","errorCode":null,"errorMessage":"Cannot apply [-] operation to type [boolean]","messagePattern":"Cannot apply \\[-\\] operation to type \\[boolean\\]","errorType":"exception","errorClass":"ClassCastException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java","lineNumber":90,"sourceCode":"\n    private static int neg(int v) {\n        return -v;\n    }\n\n    private static long neg(long v) {\n        return -v;\n    }\n\n    private static float neg(float v) {\n        return -v;\n    }\n\n    private static double neg(double v) {\n        return -v;\n    }\n\n    private static boolean neg(boolean v) {\n        throw new ClassCastException(\"Cannot apply [-] operation to type [boolean]\");\n    }\n\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        }","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/DefMath.java#L72-L108","documentation":"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.","triggerScenarios":"A Painless script applies unary minus to a def variable holding a Boolean at runtime. Example: `def x = true; def y = -x;`","commonSituations":"A script receives a boolean field and mistakenly applies arithmetic negation. Mixing logical and arithmetic operations on def-typed values without type guards.","solutions":["Verify the operand is numeric, not boolean, before negation.","Use an explicit type declaration (int, long, double) instead of def.","Guard with instanceof and branch to handle boolean separately."],"exampleFix":"// before\ndef x = doc['flag'].value;\ndef y = -x;\n\n// after\ndef x = doc['flag'].value;\nif (x instanceof Number) {\n    def y = -(long) x;\n}","handlingStrategy":"type-guard","validationCode":"// Painless: ensure the value is numeric before unary negation\ndef x = doc['flag'].value;\nif (x instanceof Number) {\n    def y = -(double) x;\n}","typeGuard":"// Painless type guard for numeric types\ndef isNumeric(def value) {\n    return value instanceof Number;\n}","tryCatchPattern":null,"preventionTips":["Declare numeric variables as int, long, double, or float instead of def.","Check with instanceof before applying unary negation on def values.","Verify that document fields used in arithmetic are mapped as numeric, not boolean."],"tags":["painless","def-type","unary","boolean","type-mismatch","arithmetic"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}