flowable/flowable-engine · error · FlowableIllegalArgumentException

Booleans and null cannot be used in 'greater than' condition

Error message

Booleans and null cannot be used in 'greater than' condition

What it means

Flowable variable queries reject null and Boolean values for GREATER_THAN operators, because neither can be meaningfully ordered in SQL variable comparisons. The check lives in AbstractVariableQueryImpl.addVariable, the shared validation path for all variable query value setters. It is thrown as FlowableIllegalArgumentException at query-construction time, before any database call.

Solutions

  1. Use EQUALS/NOT_EQUALS (or EXISTS/NOT_EXISTS for null) instead of a greater-than operator for null or boolean values
  2. Change the variable to a comparable type (number, date, string) if ordering semantics are needed
  3. Guard the call site: only invoke greaterThan setters when the value is non-null and not Boolean
  4. Use in-memory filtering of query results when boolean/null ordering logic is truly required

Example fix

// before
historyService.createHistoricVariableInstanceQuery()
    .variableValueGreaterThan("active", true);
// after
historyService.createHistoricVariableInstanceQuery()
    .variableValueEquals("active", true);
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.variableValueGreaterThan(name, value);

Type guard

static boolean isComparableVarValue(Object v) {
    return v != null && !(v instanceof Boolean);
}

Try / catch

try {
    query.variableValueGreaterThan(name, value);
} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {
    // fall back to equals or log and skip clause
}

Prevention

When it happens

Trigger: Calling any of taskVariableValueGreaterThan / processVariableValueGreaterThan / scopedVariableValueGreaterThan (or the variants routed through addVariable) with value=null or a Boolean, e.g. queryVariableValueGreaterThan("flag", true).

Common situations: Passing a Boolean flag to numeric comparison APIs; passing null intending 'any value'; auto-generating queries from maps that contain nulls or booleans; migrating code from EQUALS queries to GREATER_THAN without revisiting value types.

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/cca4eb9d27b0e59a. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/AbstractVariableQueryImpl.java:307

    @SuppressWarnings("unchecked")
    protected T scopedVariableNotExists(String name, String scopeType) {
        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");
            }

View on GitHub (pinned to d6d39ce1c6)