{"record":{"id":"ae7328b005491a21","repo":"flowable/flowable-engine","slug":"booleans-and-null-cannot-be-used-in-less-than-or","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":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/AbstractVariableQueryImpl.java","lineNumber":313,"sourceCode":"    protected void addVariable(String name, Object value, QueryOperator operator, boolean localScope) {\n        this.addVariable(name, value, operator, null, localScope);\n    }\n\n    protected void addVariable(String name, Object value, QueryOperator operator, String scopeType, boolean localScope) {\n        if (name == null) {\n            throw new FlowableIllegalArgumentException(\"name is null\");\n        }\n        if (value == null || isBoolean(value)) {\n            // Null-values and booleans can only be used in EQUALS, NOT_EQUALS, EXISTS and NOT_EXISTS\n            switch (operator) {\n                case GREATER_THAN:\n                    throw new FlowableIllegalArgumentException(\"Booleans and null cannot be used in 'greater than' condition\");\n                case LESS_THAN:\n                    throw new FlowableIllegalArgumentException(\"Booleans and null cannot be used in 'less than' condition\");\n                case GREATER_THAN_OR_EQUAL:\n                    throw new FlowableIllegalArgumentException(\"Booleans and null cannot be used in 'greater than or equal' condition\");\n                case LESS_THAN_OR_EQUAL:\n                    throw new FlowableIllegalArgumentException(\"Booleans and null cannot be used in 'less than or equal' condition\");\n                default:\n                    break;\n            }\n\n            if (operator == QueryOperator.EQUALS_IGNORE_CASE && !(value instanceof String)) {\n                throw new FlowableIllegalArgumentException(\"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 FlowableIllegalArgumentException(\"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 FlowableIllegalArgumentException(\"Only string values can be used with 'like' condition\");\n            }\n        }\n\n        queryVariableValues.add(new QueryVariableValue(name, value, operator, localScope, scopeType));","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/AbstractVariableQueryImpl.java#L295-L331","documentation":"LESS_THAN_OR_EQUAL comparisons cannot be combined with null or Boolean variable values in Flowable, because such values have no defined ordering. The validation in AbstractVariableQueryImpl.addVariable throws FlowableIllegalArgumentException as soon as the clause is registered. This is a programming/API-usage error, not an environment issue.","triggerScenarios":"Any variable query builder call that reaches addVariable with operator LESS_THAN_OR_EQUAL and a null or Boolean value, e.g. processVariableValueLessThanOrEqual(\"retry\", true).","commonSituations":"Treating boolean columns as numeric thresholds; null coming from an unset date bound; reflection-based query builders forwarding raw Object values.","solutions":["Pass only non-null comparable values (numbers, dates, strings) to lessThanOrEqual","Use variableValueEquals for boolean conditions and variableValueExists for null checks","Add a caller-side check: skip the clause or use EQUALS when value is null/Boolean","Re-model the variable to store a comparable type"],"exampleFix":"// before\nq.variableValueLessThanOrEqual(\"done\", Boolean.TRUE);\n// after\nq.variableValueEquals(\"done\", Boolean.TRUE);","handlingStrategy":"validation","validationCode":"if (value == null || value instanceof Boolean) {\n    throw new IllegalArgumentException(\"LessThanOrEqual requires a non-null non-boolean value\");\n}\nquery.variableValueLessThanOrEqual(name, value);","typeGuard":"static boolean canOrder(Object v) {\n    return v != null && !(v instanceof Boolean);\n}","tryCatchPattern":"try {\n    query.variableValueLessThanOrEqual(name, value);\n} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {\n    // use equals or omit condition\n}","preventionTips":["Convert boolean conditions to equals clauses","Guard optional date/number bounds against null","Keep variable definitions typed consistently with query operators","Write tests for edge value types (null, Boolean) in query construction"],"tags":["flowable","validation","query","null"],"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-18T11:17:12.947Z"}