flowable/flowable-engine · error · org.flowable.common.engine.api.FlowableIllegalArgumentException
processInstanceIds is empty
Error message
processInstanceIds is empty
What it means
HistoricVariableInstanceQueryImpl.processInstanceIds requires a non-null, non-empty collection and throws FlowableIllegalArgumentException when the collection is null or empty. An empty IN clause would generate invalid SQL, so the builder validates eagerly. This error occurs at query-construction time.
Source
Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/HistoricVariableInstanceQueryImpl.java:92
@Override
public HistoricVariableInstanceQuery id(String id) {
this.id = id;
return this;
}
@Override
public HistoricVariableInstanceQueryImpl processInstanceId(String processInstanceId) {
if (processInstanceId == null) {
throw new FlowableIllegalArgumentException("processInstanceId is null");
}
this.processInstanceId = processInstanceId;
return this;
}
@Override
public HistoricVariableInstanceQuery processInstanceIds(Collection<String> processInstanceIds) {
if (processInstanceIds == null || processInstanceIds.isEmpty()) {
throw new FlowableIllegalArgumentException("processInstanceIds is empty");
}
this.processInstanceIds = processInstanceIds;
return this;
}
@Override
public HistoricVariableInstanceQueryImpl executionId(String executionId) {
if (executionId == null) {
throw new FlowableIllegalArgumentException("Execution id is null");
}
if (excludeLocalVariables) {
throw new FlowableIllegalArgumentException("Cannot use executionId together with excludeLocalVariables");
}
this.executionId = executionId;
return this;
}
@OverrideView on GitHub (pinned to d6d39ce1c6)
Solutions
- Skip the query (or return an empty result directly) when the collection is empty
- Only add the processInstanceIds clause when the collection has elements
- Ensure the upstream query that produces the ids actually matches expected data
- Defensively default to a sentinel if querying all instances is intended (or use no clause)
Example fix
// before
query.processInstanceIds(ids);
// after
if (ids != null && !ids.isEmpty()) {
query.processInstanceIds(ids);
} else {
return Collections.emptyList();
} Defensive patterns
Strategy: validation
Validate before calling
if (ids == null || ids.isEmpty()) {
return Collections.emptyList(); // nothing to query
}
query.processInstanceIds(ids); Type guard
static boolean hasIds(Collection<String> ids) {
return ids != null && !ids.isEmpty();
} Try / catch
try {
query.processInstanceIds(ids);
} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {
// return empty result set for empty input
} Prevention
- Treat empty id lists as 'no results', not 'all results'
- Check upstream queries for zero matches before batch lookups
- Wrap collection-based clauses in helper methods that handle empty input
- Add early returns for empty collections in service code
When it happens
Trigger: Calling createHistoricVariableInstanceQuery().processInstanceIds(Collections.emptyList()) or processInstanceIds(null), commonly when the id list comes from an upstream query that matched nothing.
Common situations: Batch lookups where the previous query returned zero rows; request parameters with no selected instances; building queries in loops that start with an empty accumulator.
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
- Set of process instance ids is empty
- Set of called process instance ids is empty
- Empty appsDefinitionIds
- historic case instanceIds are empty
- groupIds are empty
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/aaadb899e76f976a.
Report an issue: GitHub.