flowable/flowable-engine · error · FlowableIllegalArgumentException
Set of process definition ids is empty
Error message
Set of process definition ids is empty
What it means
ProcessInstanceQueryImpl.processDefinitionIds(Set<String>) throws FlowableIllegalArgumentException('Set of process definition ids is empty') when the supplied set is non-null but has no elements. An empty set would produce an invalid or always-false IN() clause, so Flowable rejects it explicitly right after the null check, before storing the value on the query or OR-query object.
Solutions
- Check isEmpty() before calling and skip the filter (or return an empty result immediately) when the set is empty
- Decide explicitly: an empty set should usually mean 'return nothing' — short-circuit with query.listPage(0,0) or an impossible filter instead
- Investigate why the id set is empty (permission/tenant logic) if that state is unexpected
- Catch FlowableIllegalArgumentException around query construction to give a precise message
Example fix
// before
Set<String> ids = resolvePermittedDefinitionIds(user);
query.processDefinitionIds(ids); // throws when user has no permissions
// after
Set<String> ids = resolvePermittedDefinitionIds(user);
if (ids == null || ids.isEmpty()) {
return Collections.emptyList(); // no permitted definitions -> no results
}
query.processDefinitionIds(ids); Defensive patterns
Strategy: validation
Validate before calling
if (ids == null || ids.isEmpty()) {
return Collections.emptyList(); // nothing can match an empty IN clause
}
query.processDefinitionIds(ids); Type guard
boolean hasIds(Set<String> ids) { return ids != null && !ids.isEmpty(); } Try / catch
try {
query.processDefinitionIds(ids);
} catch (FlowableIllegalArgumentException e) {
return Collections.emptyList(); // empty set = no matches by convention
} Prevention
- Decide the semantics of an empty id set (no results) and short-circuit before querying
- Check isEmpty() alongside null whenever passing collections to IN-style filters
- Investigate unexpected empty sets from permission/tenant resolution logic
- Add tests where filters reduce the id set to zero elements
When it happens
Trigger: Calling .processDefinitionIds(Collections.emptySet()) or passing a set that was filtered down to zero elements (e.g. no definitions match the user's permissions, or ids were removed before the call).
Common situations: Multi-tenant apps where a user belongs to no tenant and the permitted-definition set ends up empty; batch jobs whose filter criteria matched nothing; tests passing an empty set expecting 'no filter' semantics.
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
- Candidate group list is empty
- Involved groups are empty
- involvedGroups are empty
- parentScopeIds is null or empty
- rootScopeIds is null or empty
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/7f1dc73f25cb636c.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ProcessInstanceQueryImpl.java:423
if (processDefinitionId == null) {
throw new FlowableIllegalArgumentException("Process definition id is null");
}
if (inOrStatement) {
this.currentOrQueryObject.processDefinitionId = processDefinitionId;
} else {
this.processDefinitionId = processDefinitionId;
}
return this;
}
@Override
public ProcessInstanceQuery processDefinitionIds(Set<String> processDefinitionIds) {
if (processDefinitionIds == null) {
throw new FlowableIllegalArgumentException("Set of process definition ids is null");
}
if (processDefinitionIds.isEmpty()) {
throw new FlowableIllegalArgumentException("Set of process definition ids is empty");
}
if (inOrStatement) {
this.currentOrQueryObject.processDefinitionIds = processDefinitionIds;
} else {
this.processDefinitionIds = processDefinitionIds;
}
return this;
}
@Override
public ProcessInstanceQueryImpl processDefinitionKey(String processDefinitionKey) {
if (processDefinitionKey == null) {
throw new FlowableIllegalArgumentException("Process definition key is null");
}
if (inOrStatement) {
this.currentOrQueryObject.processDefinitionKey = processDefinitionKey;View on GitHub (pinned to d6d39ce1c6)