{"record":{"id":"55bd226138d9963d","repo":"flowable/flowable-engine","slug":"booleans-and-null-cannot-be-used-in-less-than-or-55bd22","errorCode":null,"errorMessage":"Booleans and null cannot be used in 'less than or equal' condition","messagePattern":"Booleans and null cannot be used in 'less than or equal' condition","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/AbstractVariableQueryImpl.java","lineNumber":184,"sourceCode":"        addVariable(name, value, QueryOperator.LIKE_IGNORE_CASE, localScope);\n        return (T) this;\n    }\n\n    private void addVariable(String name, Object value, QueryOperator operator, boolean localScope) {\n        if (name == null) {\n            throw new ActivitiIllegalArgumentException(\"name is null\");\n        }\n        if (value == null || isBoolean(value)) {\n            // Null-values and booleans can only be used in EQUALS and NOT_EQUALS\n            switch (operator) {\n                case GREATER_THAN:\n                    throw new ActivitiIllegalArgumentException(\"Booleans and null cannot be used in 'greater than' condition\");\n                case LESS_THAN:\n                    throw new ActivitiIllegalArgumentException(\"Booleans and null cannot be used in 'less than' condition\");\n                case GREATER_THAN_OR_EQUAL:\n                    throw new ActivitiIllegalArgumentException(\"Booleans and null cannot be used in 'greater than or equal' condition\");\n                case LESS_THAN_OR_EQUAL:\n                    throw new ActivitiIllegalArgumentException(\"Booleans and null cannot be used in 'less than or equal' condition\");\n            }\n\n            if (operator == QueryOperator.EQUALS_IGNORE_CASE && !(value instanceof String)) {\n                throw new ActivitiIllegalArgumentException(\"Only string values can be used with 'equals ignore case' condition\");\n            }\n\n            if (operator == QueryOperator.NOT_EQUALS_IGNORE_CASE && !(value instanceof String)) {\n                throw new ActivitiIllegalArgumentException(\"Only string values can be used with 'not equals ignore case' condition\");\n            }\n\n            if ((operator == QueryOperator.LIKE || operator == QueryOperator.LIKE_IGNORE_CASE) && !(value instanceof String)) {\n                throw new ActivitiIllegalArgumentException(\"Only string values can be used with 'like' condition\");\n            }\n        }\n        queryVariableValues.add(new QueryVariableValue(name, value, operator, localScope));\n    }\n\n    private boolean isBoolean(Object value) {","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/AbstractVariableQueryImpl.java#L166-L202","documentation":"ActivitiIllegalArgumentException thrown by addVariable when a null or Boolean value is used with the LESS_THAN_OR_EQUAL operator. As with other ordering operators, null/boolean values are restricted to EQUALS/NOT_EQUALS, so inclusive upper-bound conditions reject them eagerly.","triggerScenarios":"Calling variableValueLessThanOrEqual(name, null) or variableValueLessThanOrEqual(name, aBoolean) on a query, or dynamic builders adding the operator with a null/Boolean operand.","commonSituations":"Range-filter UIs with empty upper-bound inputs, or type drift where a numeric variable is now stored as Boolean.","solutions":["Only add the condition when the upper bound is non-null and non-boolean.","Use variableValueEquals for boolean values.","Sanitize filter input before mapping it to query operators."],"exampleFix":"// before\nquery.taskVariableLessThanOrEqual(\"score\", upper);\n// after\nif (upper != null && !(upper instanceof Boolean)) {\n    query.taskVariableLessThanOrEqual(\"score\", upper);\n}","handlingStrategy":"type-guard","validationCode":"if (upperBound != null && !(upperBound instanceof Boolean)) {\n    query.taskVariableLessThanOrEqual(name, upperBound);\n}","typeGuard":"boolean isOrderable(Object v) { return v != null && !(v instanceof Boolean); }","tryCatchPattern":"try {\n    query.taskVariableLessThanOrEqual(name, upperBound);\n} catch (ActivitiIllegalArgumentException e) {\n    log.warn(\"Skipping upper-bound filter: {}\", e.getMessage());\n}","preventionTips":["Null-check upper bounds before adding range conditions","Handle booleans with equality conditions only","Write tests for empty range-filter inputs"],"tags":["activiti","query","boolean","operator"],"backgroundTag":"invalid-argument-value","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T16:30:33.424Z"}