flowable/flowable-engine · error · FlowableIllegalArgumentException
Unsupported variable query operation: ${variable.getVariable
Error message
Unsupported variable query operation: ${variable.getVariableOperation()} What it means
Catch-all FlowableIllegalArgumentException in the operation switch: the requested QueryVariableOperation has no branch in the historic case instance variable query builder, so it is unsupported for this endpoint.
Source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/caze/HistoricCaseInstanceBaseResource.java:392
case LESS_THAN:
caseInstanceQuery.variableValueLessThan(variable.getName(), actualValue);
break;
case LESS_THAN_OR_EQUALS:
caseInstanceQuery.variableValueLessThanOrEqual(variable.getName(), actualValue);
break;
case EXISTS:
caseInstanceQuery.variableExists(variable.getName());
break;
case NOT_EXISTS:
caseInstanceQuery.variableNotExists(variable.getName());
break;
default:
throw new FlowableIllegalArgumentException("Unsupported variable query operation: " + variable.getVariableOperation());
}
}
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Use a supported operation: equals, notEquals, equalsIgnoreCase, notEqualsIgnoreCase, like, likeIgnoreCase, greaterThan, greaterThanOrEquals, lessThan, lessThanOrEquals, exists, notExists
- Align client Flowable REST version with the server version
- Log and inspect the exact operation string being sent
- Add server-side handling if you own a fork and need the extra operation
Example fix
// before
{"name":"x","operation":"between","value":1}
// after
{"name":"x","operation":"greaterThanOrEquals","value":1} // plus a lessThanOrEquals variable Defensive patterns
Strategy: validation
Validate before calling
Set<String> SUPPORTED = Set.of("equals","notEquals","equalsIgnoreCase","notEqualsIgnoreCase","like","likeIgnoreCase","greaterThan","greaterThanOrEquals","lessThan","lessThanOrEquals","exists","notExists");
if (!SUPPORTED.contains(op)) throw new IllegalArgumentException("Unsupported operation: " + op); Type guard
boolean isSupportedOperation(String op) {
return java.util.EnumSet.allOf(QueryVariableOperation.class).stream()
.map(Enum::name).map(n -> n.replace('_',' ').toLowerCase()).anyMatch(op::equals);
} Try / catch
try { ... } catch (FlowableIllegalArgumentException e) {
log.error("Unsupported variable operation: {}", e.getMessage());
return badRequest(e.getMessage());
} Prevention
- Pin client and server Flowable versions together
- Use only operations listed in the endpoint docs
- Integration-test queries after version upgrades
When it happens
Trigger: POST query with an operation value that deserializes to an enum the switch does not handle (newer/older enum member, or a custom operation name).
Common situations: Client and server version mismatch — client sends an operation added in a newer Flowable version; typos that still deserialize; copy-pasted operation from a task/process query supporting more operations.
Related errors
- Unsupported variable query operation:
- Unsupported variable query operation: ${operation}
- 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/e62c5d5e0483ba0d.
Report an issue: GitHub.