flowable/flowable-engine · error · FlowableIllegalArgumentException
Set of process instance ids is empty
Error message
Set of process instance ids is empty
What it means
ExecutionQueryImpl.processInstanceIds(Set<String>) also rejects an empty set with FlowableIllegalArgumentException("Set of process instance ids is empty"), because an IN () clause with no values is invalid SQL. The library forces callers to make an explicit decision when there is nothing to query.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ExecutionQueryImpl.java:315
public ExecutionQueryImpl processInstanceId(String processInstanceId) {
if (processInstanceId == null) {
throw new FlowableIllegalArgumentException("Process instance id is null");
}
if (inOrStatement) {
this.currentOrQueryObject.processInstanceId = processInstanceId;
} else {
this.processInstanceId = processInstanceId;
}
return this;
}
@Override
public ExecutionQuery processInstanceIds(Set<String> processInstanceIds) {
if (processInstanceIds == null) {
throw new FlowableIllegalArgumentException("Set of process instance ids is null");
}
if (processInstanceIds.isEmpty()) {
throw new FlowableIllegalArgumentException("Set of process instance ids is empty");
}
if (inOrStatement) {
this.currentOrQueryObject.processInstanceIds = processInstanceIds;
} else {
this.processInstanceIds = processInstanceIds;
}
return this;
}
@Override
public ExecutionQueryImpl rootProcessInstanceId(String rootProcessInstanceId) {
if (rootProcessInstanceId == null) {
throw new FlowableIllegalArgumentException("Root process instance id is null");
}
if (inOrStatement) {
this.currentOrQueryObject.rootProcessInstanceId = rootProcessInstanceId;
} else {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Guard with ids.isEmpty() before building the query and return an empty result early
- Fall back to a different query (e.g. by processDefinitionKey) when no ids are known
- Skip executing the query entirely in that code path
- Catch FlowableIllegalArgumentException and treat it as 'no results' if acceptable
Example fix
// before
Execution execution = runtimeService.createExecutionQuery().processInstanceIds(ids).singleResult();
// after
if (ids == null || ids.isEmpty()) {
return Collections.emptyList();
}
List<Execution> executions = runtimeService.createExecutionQuery().processInstanceIds(ids).list(); Defensive patterns
Strategy: validation
Validate before calling
if (ids == null || ids.isEmpty()) {
return Collections.emptyList();
} Type guard
boolean isNonEmptyIdSet(Set<String> ids) {
return ids != null && !ids.isEmpty();
} Try / catch
try {
return query.processInstanceIds(ids).list();
} catch (FlowableIllegalArgumentException e) {
return Collections.emptyList();
} Prevention
- Short-circuit to an empty result when the id set is empty
- Never issue an IN-query with zero values — it is rejected by design
- Log when an empty candidate set silently skips a query so callers can detect it
When it happens
Trigger: Calling processInstanceIds with a set that was created but never populated, or filtered down to zero elements before the query runs.
Common situations: Building ids from a prior search whose results were empty; filtering by tenant/permission removed all candidates; batch job with no work items for this run.
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
- Empty appsDefinitionIds
- scopeIds is empty
- Could not find an app definition with id '<appDefinitionId>
- Could not find a deployment with id '<deploymentId>
- appsDefinitionIds is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/5eb0ad67351ac0ac.
Report an issue: GitHub.