{"record":{"id":"2e0c9bf419383b40","repo":"flowable/flowable-engine","slug":"booleans-and-null-cannot-be-used-in-less-than-co-2e0c9b","errorCode":null,"errorMessage":"Booleans and null cannot be used in 'less than' condition","messagePattern":"Booleans and null cannot be used in 'less than' condition","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/AbstractVariableQueryImpl.java","lineNumber":180,"sourceCode":"    }\n\n    @SuppressWarnings(\"unchecked\")\n    public T variableValueLikeIgnoreCase(String name, String value, boolean localScope) {\n        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        }","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/AbstractVariableQueryImpl.java#L162-L198","documentation":"ActivitiIllegalArgumentException thrown by addVariable when a null or Boolean value is used with the LESS_THAN operator. The engine forbids ordering comparisons on null/boolean variable values since only EQUALS/NOT_EQUALS are meaningful for them. Validation occurs eagerly when the query condition is added.","triggerScenarios":"Calling variableValueLessThan(name, null) or variableValueLessThan(name, aBoolean); also dynamic builders that choose LESS_THAN based on data whose value turns out to be Boolean or null.","commonSituations":"Generic search forms map 'value < X' filters with an empty (null) input, or a variable's Java type changed from numeric to Boolean and old range queries now fail.","solutions":["Skip the condition when the value is null.","Use variableValueEquals for boolean variables instead of range comparisons.","Validate input types at the application boundary so booleans never reach LESS_THAN conditions."],"exampleFix":"// before\nif (filterValue != null) query.taskVariableLessThan(\"count\", filterValue);\n// after\nif (filterValue != null && !(filterValue instanceof Boolean)) {\n    query.taskVariableLessThan(\"count\", filterValue);\n}","handlingStrategy":"type-guard","validationCode":"if (value != null && !(value instanceof Boolean)) {\n    query.taskVariableLessThan(name, value);\n}","typeGuard":"boolean isOrderable(Object v) { return v != null && !(v instanceof Boolean); }","tryCatchPattern":"try {\n    query.taskVariableLessThan(name, value);\n} catch (ActivitiIllegalArgumentException e) {\n    log.warn(\"Skipping less-than filter: {}\", e.getMessage());\n}","preventionTips":["Skip empty range filters instead of passing null","Map boolean variables only to equality conditions","Validate operator/value pairs centrally before building queries"],"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"}