flowable/flowable-engine · error · FlowableIllegalArgumentException
Unsupported variable query operation:
Error message
Unsupported variable query operation:
What it means
The switch over QueryVariableOperation in TaskBaseResource.addTaskvariables has a default branch that throws when the operation string does not map to any known enum constant handler. Practically this means the client supplied an unrecognized/unsupported variable operation name.
Solutions
- Use an exact QueryVariableOperation value: equals, notEquals, equalsIgnoreCase, notEqualsIgnoreCase, like, likeIgnoreCase, greaterThan, greaterThanOrEquals, lessThan, lessThanOrEquals, exists, notExists
- Check the Flowable version's QueryVariableOperation enum for supported names
- Fix typos in the query body
Example fix
// before
{"name":"x","operation":"contains","value":"abc"}
// after
{"name":"x","operation":"like","value":"%abc%"} Defensive patterns
Strategy: validation
Validate before calling
const OPS = ['equals','notEquals','equalsIgnoreCase','notEqualsIgnoreCase','like','likeIgnoreCase','greaterThan','greaterThanOrEquals','lessThan','lessThanOrEquals','exists','notExists'];
function validateOp(v) {
if (!OPS.includes(v.operation)) {
throw new Error(`Unsupported variable operation: ${v.operation}`);
}
} Type guard
const isKnownOp = (op) => OPS.includes(op);
Try / catch
try {
const res = await flowable.queryTasks(body);
} catch (e) {
if (e.message && e.message.includes('Unsupported variable query operation')) {
// correct the operation name against the server's Flowable version
} else throw e;
} Prevention
- Keep an enum of valid operations matching your Flowable version
- Watch for version drift: newer operations may not exist on older servers
- Use typed clients instead of raw strings for the operation field
When it happens
Trigger: POST/GET /runtime/tasks with a taskVariables entry whose 'operation' is misspelled or not a valid QueryVariableOperation value (e.g. 'equal', 'contains'), or a newer operation sent to an older Flowable REST version.
Common situations: Typos in operation names; API version mismatch between client docs and server; copying operation names from a different engine (e.g. process-variable-only ops).
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- A group or a user is required to create an identity link.
- A group or a user is required to create an identity link.
- Comment text is required.
- Either processDefinitionId, processDefinitionKey or message…
- Identity link family should be 'users' or 'groups'.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/163f4b99b5885913.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskBaseResource.java:476
case LIKE_IGNORE_CASE:
if (actualValue instanceof String) {
taskQuery.taskVariableValueLikeIgnoreCase(variable.getName(), (String) actualValue);
} else {
throw new FlowableIllegalArgumentException("Only string variable values are supported using like, but was: " + actualValue.getClass().getName());
}
break;
case EXISTS:
taskQuery.taskVariableExists(variable.getName());
break;
case NOT_EXISTS:
taskQuery.taskVariableNotExists(variable.getName());
break;
default:
throw new FlowableIllegalArgumentException("Unsupported variable query operation: " + variable.getVariableOperation());
}
}
}
protected void addProcessvariables(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);View on GitHub (pinned to d6d39ce1c6)