flowable/flowable-engine · error · FlowableIllegalArgumentException
Variable operation is missing for variable:
Error message
Variable operation is missing for variable:
What it means
Thrown as FlowableIllegalArgumentException when a variable query predicate supplied to the historic variable instance query has no 'operation' field. The REST query endpoint accepts a variables filter array where each entry needs name, value, and operation (e.g. equals, like, greaterThan); operation is mandatory. Without it the query cannot know which operator to apply, so the request is rejected as invalid (HTTP 400).
Source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/variable/HistoricVariableInstanceBaseResource.java:119
}
public RestVariable getVariableFromRequest(boolean includeBinary, String varInstanceId) {
HistoricVariableInstance varObject = historyService.createHistoricVariableInstanceQuery().id(varInstanceId).singleResult();
if (varObject == null) {
throw new FlowableObjectNotFoundException("Historic variable instance '" + varInstanceId + "' couldn't be found.", VariableInstanceEntity.class);
} else {
if (restApiInterceptor != null) {
restApiInterceptor.accessHistoryVariableInfoById(varObject);
}
return restResponseFactory.createRestVariable(varObject.getVariableName(), varObject.getValue(), null, varInstanceId, CmmnRestResponseFactory.VARIABLE_HISTORY_VARINSTANCE, includeBinary);
}
}
protected void addVariables(HistoricVariableInstanceQuery variableInstanceQuery, List<QueryVariable> variables) {
for (QueryVariable variable : variables) {
if (variable.getVariableOperation() == null) {
throw new FlowableIllegalArgumentException("Variable operation is missing for variable: " + variable.getName());
}
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()) {
case EQUALS:
variableInstanceQuery.variableValueEquals(variable.getName(), actualValue);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Add the required operation to each variable filter, e.g. {"name":"status","value":"done","operation":"equals"}.
- Use one of the supported operations: equals, notEquals, greaterThan, greaterThanOrEquals, lessThan, lessThanOrEquals, like, ignoreCaseEquals (per QueryVariable.QueryVariableOperation).
- Fix JSON key spelling/casing so the operation field actually binds during deserialization.
- Validate the query payload client-side before sending: every variable entry must have non-null name (or intentionally nameless) and operation.
Example fix
// before: 400 - operation missing
{"variables":[{"name":"status","value":"done"}]}
// after
{"variables":[{"name":"status","value":"done","operation":"equals"}]} Defensive patterns
Strategy: validation
Validate before calling
if (variables.stream().anyMatch(v -> v.getOperation() == null)) {
throw new IllegalArgumentException("every variable filter needs an operation (equals, like, ...)");
} Try / catch
try {
HistoricVariableInstanceListResponse r = query(variables);
} catch (FlowableIllegalArgumentException e) {
// HTTP 400: invalid variable filter payload
} Prevention
- Always include "operation" in variable filter entries
- Use supported operations from QueryVariable.QueryVariableOperation
- Check JSON key spelling so operation binds on deserialization
- Test query payloads against the endpoint before wiring them into clients
When it happens
Trigger: POST-style query GET /cmmn-history/historic-variable-instances?variables=... (or query body) with a variable entry like {"name":"status","value":"done"} lacking "operation":"equals", or a client serializing QueryVariable objects with a null variableOperation.
Common situations: Hand-built query strings that omit the operation parameter, older client SDKs whose model predates the operation field, or JSON payloads where the operation key is misspelled (e.g. 'op') so it deserializes to null.
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
- Variable value is missing for variable:
- Value-only query (without a variable-name) is not supported
- Variable operation is missing for variable: ${variable.getNa
- Variable value is missing for variable: ${variable.getName()
- Value-only query (without a variable-name) is only supported
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/aa602d985f8b4fc6.
Report an issue: GitHub.