flowable/flowable-engine · error · FlowableIllegalArgumentException
variableNames are null or empty
Error message
variableNames are null or empty
What it means
ProcessInstanceQueryImpl.includeProcessVariables(Collection<String>) narrows which process variables are included in query results. Flowable throws FlowableIllegalArgumentException when the collection is null or empty because including 'zero named variables' is meaningless — callers should either include all variables (no-arg includeProcessVariables()) or a specific non-empty list.
Solutions
- Pass a non-empty collection of variable names, or call the no-arg includeProcessVariables() to include all variables
- Guard the call: skip it entirely when the collection is empty
- Verify where the variable-name list is built and why it ends up empty
- Catch FlowableIllegalArgumentException and degrade to including all variables if acceptable
Example fix
// before
query.includeProcessVariables(variableNames); // may be empty
// after
if (variableNames != null && !variableNames.isEmpty()) {
query.includeProcessVariables(variableNames);
} else {
query.includeProcessVariables(); // include all variables
} Defensive patterns
Strategy: validation
Validate before calling
if (variableNames == null || variableNames.isEmpty()) {
// fall back to include-all instead of calling the collection overload
} Type guard
boolean hasVariableNames = variableNames != null && !variableNames.isEmpty();
Try / catch
try {
query.includeProcessVariables(variableNames);
} catch (FlowableIllegalArgumentException e) {
query.includeProcessVariables();
} Prevention
- Remember the no-arg includeProcessVariables() means 'all variables'
- Validate dynamic column selections before query construction
- Document that the collection overload requires a non-empty list
When it happens
Trigger: Calling includeProcessVariables(null), includeProcessVariables(Collections.emptyList()), or passing a variable-name list that was emptied upstream (e.g., an empty user selection of 'columns to include').
Common situations: Dynamic report builders where the user deselected all variable columns; code that used to pass a full list and now receives an empty list after a refactor; confusion between the no-arg and collection-arg overloads of includeProcessVariables.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- callbackIds is null or empty
- Involved groups are empty
- parentScopeIds is null or empty
- rootScopeIds is null or empty
- at least one of userId or groups must be provided
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/8010c0aa0cd75e49.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ProcessInstanceQueryImpl.java:662
public ProcessInstanceQuery suspended() {
if (inOrStatement) {
this.currentOrQueryObject.suspensionState = SuspensionState.SUSPENDED;
} else {
this.suspensionState = SuspensionState.SUSPENDED;
}
return this;
}
@Override
public ProcessInstanceQuery includeProcessVariables() {
this.includeProcessVariables = true;
return this;
}
@Override
public ProcessInstanceQuery includeProcessVariables(Collection<String> variableNames) {
if (variableNames == null || variableNames.isEmpty()) {
throw new FlowableIllegalArgumentException("variableNames are null or empty");
}
includeProcessVariables();
this.variableNamesToInclude = new LinkedHashSet<>(variableNames);
return this;
}
@Override
public ProcessInstanceQuery withJobException() {
this.withJobException = true;
return this;
}
@Override
public ProcessInstanceQuery processInstanceName(String name) {
if (inOrStatement) {
this.currentOrQueryObject.name = name;
} else {
this.name = name;View on GitHub (pinned to d6d39ce1c6)