flowable/flowable-engine · error · FlowableIllegalArgumentException

Booleans and null cannot be used in 'greater than or equal'…

Error message

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

What it means

GREATER_THAN_OR_EQUAL comparisons are invalid with null or Boolean values in Flowable variable queries; the ordering of such values is undefined. AbstractVariableQueryImpl.addVariable detects this combination and throws FlowableIllegalArgumentException at query build time. No database interaction occurs.

Solutions

  1. Ensure the value is a non-null comparable type (Integer, Long, Date, String) before calling
  2. Use EQUALS for booleans, EXISTS for null checks
  3. Coerce null to a sensible default or omit the clause conditionally
  4. Filter results in memory when the value may be null/boolean

Example fix

// before
if (minCount != null) q.variableValueGreaterThanOrEqual("count", minCount);
// after (still required minCount non-null numeric; for booleans use equals)
q.variableValueGreaterThanOrEqual("count", minCount == null ? 0 : minCount);
Defensive patterns

Strategy: validation

Validate before calling

if (value == null || value instanceof Boolean) {
    throw new IllegalArgumentException("GreaterThanOrEqual requires a non-null non-boolean value");
}
query.variableValueGreaterThanOrEqual(name, value);

Type guard

static boolean isOrderable(Object v) {
    return v instanceof Comparable && !(v instanceof Boolean);
}

Try / catch

try {
    query.variableValueGreaterThanOrEqual(name, value);
} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {
    // handle: use equals or skip clause
}

Prevention

When it happens

Trigger: Calling variableValueGreaterThanOrEqual (or scoped variants) with value=null or a Boolean value, e.g. taskVariableValueGreaterThanOrEqual("count", null).

Common situations: Nullable numeric values boxed into Object and passed through; boolean thresholds in feature-flag queries; copy-pasted builder code where the value type changed from Integer to Boolean/null.

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/4c473541635de58d. Report an issue: GitHub.

Appendix: source

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

    }

    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)