flowable/flowable-engine · error · org.flowable.common.engine.api.FlowableIllegalArgumentException

Only string values can be used with 'like' condition

Error message

Only string values can be used with 'like' condition

What it means

LIKE and LIKE_IGNORE_CASE comparisons in Flowable variable queries require a String value; addVariable throws this FlowableIllegalArgumentException for any other type. SQL LIKE matching is only defined for text variables, so the API rejects non-string operands eagerly.

Solutions

  1. Ensure the like pattern is a String including wildcards, e.g. "%abc%"
  2. Convert numbers/objects with String.valueOf before calling
  3. Use equals/notEquals for non-string matching
  4. Guard with value instanceof String before invoking the like setter

Example fix

// before
q.variableValueLike("orderId", 12345);
// after
q.variableValueLike("orderId", "%12345%");
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(pattern instanceof String)) {
    throw new IllegalArgumentException("like requires a String pattern");
}
query.variableValueLike(name, (String) pattern);

Type guard

static boolean isLikePattern(Object v) {
    return v instanceof String;
}

Try / catch

try {
    query.variableValueLike(name, pattern);
} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {
    // fall back to equals with String.valueOf(value)
}

Prevention

When it happens

Trigger: Calling variableValueLike or variableValueLikeIgnoreCase with a non-String value, e.g. processVariableValueLike("code", 123) or with null.

Common situations: Building wildcard searches from numeric IDs; null pattern values from optional UI input; pattern strings concatenated from non-string variables without conversion.

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/8c7bd0883737dc69. Report an issue: GitHub.

Appendix: source

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

                    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");
            }
        }

        queryVariableValues.add(new QueryVariableValue(name, value, operator, localScope, scopeType));
    }

    protected boolean isBoolean(Object value) {
        if (value == null) {
            return false;
        }
        return Boolean.class.isAssignableFrom(value.getClass()) || boolean.class.isAssignableFrom(value.getClass());
    }

    protected void ensureVariablesInitialized() {
        if (!queryVariableValues.isEmpty()) {
            for (QueryVariableValue queryVariableValue : queryVariableValues) {
                queryVariableValue.initialize(variableValueProvider);
            }

View on GitHub (pinned to d6d39ce1c6)