flowable/flowable-engine · error · FlowableIllegalArgumentException
Variable operation is missing for variable:
Error message
Variable operation is missing for variable:
What it means
FlowableIllegalArgumentException thrown by addVariables when a QueryVariable in the 'variables' query parameter lacks a variableOperation (equals/greaterThan/etc.). The historic variable query endpoint builds predicate clauses from each variable entry, and an operation is mandatory to know how to compare values. The request is rejected as a bad client request.
Source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricVariableInstanceBaseResource.java:102
}
if (queryRequest.getVariables() != null) {
addVariables(query, queryRequest.getVariables());
}
if (restApiInterceptor != null) {
restApiInterceptor.accessHistoryVariableInfoWithQuery(query, queryRequest);
}
return paginateList(allRequestParams, queryRequest, query, "variableName", allowedSortProperties,
restResponseFactory::createHistoricVariableInstanceResponseList);
}
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 operation field to each variable entry, e.g. variables=[{"name":"status","value":"active","operation":"EQUALS"}]
- URL-encode the JSON when passing it in the query string so keys are not stripped
- Check the client-side query builder actually serializes the operation attribute
- Use the documented operation values (EQUALS, NOT_EQUALS, GREATER_THAN, ...) matching QueryVariableOperation
Example fix
// before
GET /history/historic-variable-instances?variables=[{"name":"status","value":"active"}]
// after
GET /history/historic-variable-instances?variables=%5B%7B%22name%22%3A%22status%22%2C%22value%22%3A%22active%22%2C%22operation%22%3A%22EQUALS%22%7D%5D Defensive patterns
Strategy: validation
Validate before calling
clauses.forEach(c => { if (!c.operation) throw new Error(`operation missing for variable ${c.name}`); });
const qs = encodeURIComponent(JSON.stringify(clauses)); Type guard
function hasOperation(c) { return c && typeof c.operation === 'string' && c.operation.length > 0; } Try / catch
try { return await queryHistoricVariables(clauses); } catch (e) { if (String(e.message).includes('Variable operation is missing')) { console.error('malformed clause', clauses); } throw e; } Prevention
- Always build variable clauses through a helper that requires {name, value, operation}
- URL-encode the variables JSON in query strings
- Keep operation values aligned with QueryVariableOperation enum names
When it happens
Trigger: GET /history/historic-variable-instances?variables=[{"name":"status","value":"active"}] (or POST with the same JSON body) — the variable object omits the 'operation' field, or the JSON string is malformed such that operation deserializes to null.
Common situations: Hand-built query strings missing 'operation'; client library that maps variable filters but drops the operation attribute; JSON-in-URL parameter mangled by insufficient URL encoding so the operation key is lost.
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:
- Variable operation is missing for variable: ${variable.getNa
- Variable value is missing for variable: ${variable.getName()
- Value-only query (without a variable-name) is not supported.
- Value-only query (without a variable-name) is not supported
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/e025bcc402c551c1.
Report an issue: GitHub.