flowable/flowable-engine · error · FlowableIllegalArgumentException
Booleans and null cannot be used in 'less than' condition
Error message
Booleans and null cannot be used in 'less than' condition
What it means
Flowable variable queries reject null and Boolean values for the LESS_THAN operator since neither has a defined ordering in variable SQL comparisons. The guard is in AbstractVariableQueryImpl.addVariable and throws FlowableIllegalArgumentException immediately when the query clause is added. This is fail-fast API validation, not a runtime/database failure.
Solutions
- Replace LESS_THAN with EQUALS/NOT_EQUALS or EXISTS/NOT_EXISTS for null/boolean values
- Re-model the variable as a numeric or date type to allow ordering
- Validate the value before building the clause and skip or translate the condition
- Apply the comparison in application code after a broader query
Example fix
// before
query.variableValueLessThan("completed", null);
// after
query.variableValueEquals("completed", false); // or variableValueExists("completed") Defensive patterns
Strategy: validation
Validate before calling
if (value == null || value instanceof Boolean) {
throw new IllegalArgumentException("Use equals/exists operators for null or boolean variable values");
}
query.variableValueLessThan(name, value); Type guard
static boolean supportsOrdering(Object v) {
return v instanceof Number || v instanceof Date || v instanceof String;
} Try / catch
try {
query.variableValueLessThan(name, value);
} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {
// degrade to equals or drop the clause
} Prevention
- Check the value type before using less-than comparisons
- Translate boolean conditions to equals clauses
- Avoid forwarding raw Objects from generic maps into query builders
- Cover query building with unit tests for null/boolean inputs
When it happens
Trigger: Calling variableValueLessThan-style setters (routed through addVariable) with a null value or a Boolean, e.g. processVariableValueLessThan("enabled", false).
Common situations: Using a boolean flag as if it were comparable; nulls flowing from optional config into query builders; generic query-building code that forwards any Object as a comparison value.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Booleans and null cannot be used in 'greater than' condition
- appsDefinitionIds is null
- Booleans and null cannot be used in 'greater than or equal'…
- Booleans and null cannot be used in 'less than or equal'…
- Business status is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/e6f83acf6c3b8c15.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/AbstractVariableQueryImpl.java:309
addVariable(name, null, QueryOperator.NOT_EXISTS, scopeType, false);
return (T) this;
}
protected void addVariable(String name, Object value, QueryOperator operator, boolean localScope) {
this.addVariable(name, value, operator, null, localScope);
}
protected void addVariable(String name, Object value, QueryOperator operator, String scopeType, boolean localScope) {
if (name == null) {
throw new FlowableIllegalArgumentException("name is null");
}
if (value == null || isBoolean(value)) {
// Null-values and booleans can only be used in EQUALS, NOT_EQUALS, EXISTS and NOT_EXISTS
switch (operator) {
case GREATER_THAN:
throw new FlowableIllegalArgumentException("Booleans and null cannot be used in 'greater than' condition");
case LESS_THAN:
throw new FlowableIllegalArgumentException("Booleans and null cannot be used in 'less than' condition");
case GREATER_THAN_OR_EQUAL:
throw new FlowableIllegalArgumentException("Booleans and null cannot be used in 'greater than or equal' condition");
case LESS_THAN_OR_EQUAL:
throw new FlowableIllegalArgumentException("Booleans and null cannot be used in 'less than or equal' condition");
default:
break;
}
if (operator == QueryOperator.EQUALS_IGNORE_CASE && !(value instanceof String)) {
throw new FlowableIllegalArgumentException("Only string values can be used with 'equals ignore case' condition");
}
if (operator == QueryOperator.NOT_EQUALS_IGNORE_CASE && !(value instanceof String)) {
throw new FlowableIllegalArgumentException("Only string values can be used with 'not equals ignore case' condition");
}
if ((operator == QueryOperator.LIKE || operator == QueryOperator.LIKE_IGNORE_CASE) && !(value instanceof String)) {
throw new FlowableIllegalArgumentException("Only string values can be used with 'like' condition");View on GitHub (pinned to d6d39ce1c6)