flowable/flowable-engine · error · FlowableIllegalArgumentException

Value-only query (without a variable-name) is only…

Error message

Value-only query (without a variable-name) is only supported when using 'equals' operation.

What it means

This FlowableIllegalArgumentException is thrown when a task variable query criterion has no variable name (a value-only search across all variables) but uses an operation other than equals. Flowable can only implement value-only matching for the equals operation; any other operator needs a variable name to build its predicate. Raised in TaskBaseResource.addTaskvariables.

Solutions

  1. Set a variable name on the criterion, or
  2. Change the operation to equals, which is the only operation supported for value-only queries.
  3. Drop the criterion entirely if neither is possible.

Example fix

// before
{"taskVariables":[{"operation":"like","value":"%foo%"}]}
// after
{"taskVariables":[{"name":"description","operation":"like","value":"%foo%"}]}
Defensive patterns

Strategy: validation

Validate before calling

for (const v of body.taskVariables || []) {
  if ((v.name === undefined || v.name === null) && v.operation !== 'equals') {
    throw new Error('Value-only task variable query requires operation equals');
  }
}

Type guard

const isNamelessEquals = v => (v.name == null) && v.operation === 'equals';

Prevention

When it happens

Trigger: POST /cmmn-query/tasks with {"taskVariables":[{"value":"x","operation":"like"}]} or any nameless variable whose operation is not equals.

Common situations: Developers experimenting with 'search all variables for value X' then switching the operator to like/notEquals, or UI builders that omit the name field when users don't pick a variable but do pick an operator.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskBaseResource.java:378

    protected void addTaskvariables(TaskQuery taskQuery, List<QueryVariable> variables) {

        for (QueryVariable variable : variables) {
            if (variable.getVariableOperation() == null) {
                throw new FlowableIllegalArgumentException("Variable operation is missing for variable: " + variable.getName());
            }
            if (variable.getVariableOperation() != QueryVariableOperation.EXISTS && variable.getVariableOperation() != QueryVariableOperation.NOT_EXISTS) {
                if (variable.getValue() == null) {
                    throw new FlowableIllegalArgumentException("Variable value is missing for variable: " + variable.getName());
                }
            }

            boolean nameLess = variable.getName() == null;

            Object actualValue = restResponseFactory.getVariableValue(variable);

            // A value-only query is only possible using equals-operator
            if (nameLess && variable.getVariableOperation() != QueryVariableOperation.EQUALS) {
                throw new FlowableIllegalArgumentException("Value-only query (without a variable-name) is only supported when using 'equals' operation.");
            }

            switch (variable.getVariableOperation()) {

            case EQUALS:
                if (nameLess) {
                    taskQuery.taskVariableValueEquals(actualValue);
                } else {
                    taskQuery.taskVariableValueEquals(variable.getName(), actualValue);
                }
                break;

            case EQUALS_IGNORE_CASE:
                if (actualValue instanceof String) {
                    taskQuery.taskVariableValueEqualsIgnoreCase(variable.getName(), (String) actualValue);
                } else {
                    throw new FlowableIllegalArgumentException("Only string variable values are supported when ignoring casing, but was: " + actualValue.getClass().getName());
                }

View on GitHub (pinned to d6d39ce1c6)