flowable/flowable-engine · error · FlowableIllegalArgumentException

Variable operation is missing for variable:

Error message

Variable operation is missing for variable: 

What it means

HistoricTaskInstanceBaseResource.addProcessVariables validates every query variable before building the query. If a process-variable filter arrives without a variableOperation, there is no way to know how to compare the value, so FlowableIllegalArgumentException is thrown naming the variable.

Source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/task/HistoricTaskInstanceBaseResource.java:417

            case EXISTS:
                taskInstanceQuery.taskVariableExists(variable.getName());
                break;

            case NOT_EXISTS:
                taskInstanceQuery.taskVariableNotExists(variable.getName());
                break;

            default:
                throw new FlowableIllegalArgumentException("Unsupported variable query operation: " + variable.getVariableOperation());
            }
        }
    }

    protected void addProcessVariables(HistoricTaskInstanceQuery taskInstanceQuery, 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) {
                throw new FlowableIllegalArgumentException("Value-only query (without a variable-name) is not supported.");
            }

            switch (variable.getVariableOperation()) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Add variableOperation to every process variable filter entry.
  2. Use EXISTS/NOT_EXISTS if you only need presence, which also exempts you from providing a value.
  3. Add client-side validation requiring variableOperation before issuing the query.
  4. Catch FlowableIllegalArgumentException and surface which variable name was missing its operation.

Example fix

// before
{"name": "region", "value": "EU"}
// after
{"name": "region", "value": "EU", "variableOperation": "EQUALS"}
Defensive patterns

Strategy: validation

Validate before calling

for (QueryVariable v : variables) {
    if (v.getVariableOperation() == null)
        throw new IllegalArgumentException("variableOperation required for variable: " + v.getName());
}

Try / catch

try { return historyService.query(query); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().startsWith("Variable operation is missing")) { /* inspect payload for null operation */ } throw e; }

Prevention

When it happens

Trigger: GET /cmmn-history/historic-task-instances with a processVariable filter entry that has a name (and possibly value) but no variableOperation field, e.g. {"name": "region", "value": "EU"} with no operation.

Common situations: Omitting the operation when hand-crafting query URLs/JSON; a client serialization layer dropping fields named like reserved words; older API clients predating the required-operation contract.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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