flowable/flowable-engine · error · FlowableIllegalArgumentException
Unsupported variable query operation
Error message
Unsupported variable query operation: ${operation} What it means
FlowableIllegalArgumentException thrown when a query variable specifies a variableOperation that is not one of the QueryVariableOperation enum values handled by the switch (equals, notEquals, equalsIgnoreCase, notEqualsIgnoreCase, like, etc. depending on version). The operation string failed enum parsing into a supported case or fell through to default.
Solutions
- Use one of the supported operation names for this endpoint: equals, notEquals, equalsIgnoreCase, notEqualsIgnoreCase, like (check your Flowable version's QueryVariableOperation).
- Upgrade/downgrade the client so its operation vocabulary matches the server's QueryVariableOperation enum.
- Log the exact operation string from the request and compare against the enum values in the server version.
- Catch FlowableIllegalArgumentException (HTTP 400) and retry with equals.
Example fix
// before
{"variables":[{"name":"orderId","value":"42","operation":"greaterThanOrEqual"}]}
// after
{"variables":[{"name":"orderId","value":"42","operation":"equals"}]} Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = ['equals','notEquals','equalsIgnoreCase','notEqualsIgnoreCase','like'];
for (const v of query.variables) {
if (!SUPPORTED.includes(v.operation)) throw new Error(`Unsupported variable operation: ${v.operation}`);
} Type guard
const isSupportedOp = (op) => ['equals','notEquals','equalsIgnoreCase','notEqualsIgnoreCase','like'].includes(op);
Try / catch
try { /* query */ } catch (e) {
if (e.status === 400 && /Unsupported variable query operation/.test(e.message)) {
// map or degrade the operation to a supported one
} else throw e;
} Prevention
- Keep the client's operation enum in sync with your Flowable server version's QueryVariableOperation
- Fail fast client-side on unknown operations instead of sending them
- Pin client and server versions so vocabularies match
When it happens
Trigger: POST /query/process-instances or /query/executions with variables:[{"name":"orderId","value":"42","operation":"greaterThanOrEqual"}] — an operation name that either failed to parse to the enum (then it cannot reach here) or is a valid enum not supported by this switch.
Common situations: Typos in the operation name; copying operation names from other engine versions (Flowable added/removed QueryVariableOperation members across versions); client enumerates operators not supported by this endpoint.
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
- Unsupported variable query operation: " +…
- Only string variable values are supported for like, but…
- Only string variable values are supported using like, but…
- Only string variable values are supported when ignoring…
- Only string variable values are supported when ignoring…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/1384e9b962735a7a.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ExecutionBaseResource.java:193
processInstanceQuery.processVariableValueNotEquals(variable.getName(), actualValue);
} else {
processInstanceQuery.variableValueNotEquals(variable.getName(), actualValue);
}
break;
case NOT_EQUALS_IGNORE_CASE:
if (actualValue instanceof String) {
if (process) {
processInstanceQuery.processVariableValueNotEqualsIgnoreCase(variable.getName(), (String) actualValue);
} else {
processInstanceQuery.variableValueNotEqualsIgnoreCase(variable.getName(), (String) actualValue);
}
} else {
throw new FlowableIllegalArgumentException("Only string variable values are supported when ignoring casing, but was: " + actualValue.getClass().getName());
}
break;
default:
throw new FlowableIllegalArgumentException("Unsupported variable query operation: " + variable.getVariableOperation());
}
}
}
protected Execution getExecutionFromRequest(String executionId) {
Execution execution = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (execution == null) {
throw new FlowableObjectNotFoundException("Could not find an execution with id '" + executionId + "'.", Execution.class);
}
if (restApiInterceptor != null) {
restApiInterceptor.accessExecutionInfoById(execution);
}
return execution;
}
protected Map<String, Object> getVariablesToSet(List<RestVariable> restVariables) {View on GitHub (pinned to d6d39ce1c6)