flowable/flowable-engine · error · FlowableIllegalArgumentException
Set of case instance ids is null
Error message
Set of case instance ids is null
What it means
HistoricPlanItemInstanceQueryImpl.planItemInstanceCaseInstanceIds() requires a non-null Set of case instance ids; a null set raises FlowableIllegalArgumentException. The query API distinguishes null (programming error) from not calling the method (no filter).
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricPlanItemInstanceQueryImpl.java:182
this.derivedCaseDefinitionId = derivedCaseDefinitionId;
}
return this;
}
@Override
public HistoricPlanItemInstanceQuery planItemInstanceCaseInstanceId(String caseInstanceId) {
if (inOrStatement) {
this.currentOrQueryObject.caseInstanceId = caseInstanceId;
} else {
this.caseInstanceId = caseInstanceId;
}
return this;
}
@Override
public HistoricPlanItemInstanceQuery planItemInstanceCaseInstanceIds(Set<String> caseInstanceIds) {
if (caseInstanceIds == null) {
throw new FlowableIllegalArgumentException("Set of case instance ids is null");
}
if (caseInstanceIds.isEmpty()) {
throw new FlowableIllegalArgumentException("Set of case instance ids is empty");
}
if (inOrStatement) {
this.currentOrQueryObject.caseInstanceIds = caseInstanceIds;
} else {
this.caseInstanceIds = caseInstanceIds;
}
return this;
}
@Override
public HistoricPlanItemInstanceQuery planItemInstanceStageInstanceId(String stageInstanceId) {
if (inOrStatement) {
this.currentOrQueryObject.stageInstanceId = stageInstanceId;
} else {
this.stageInstanceId = stageInstanceId;View on GitHub (pinned to d6d39ce1c6)
Solutions
- Null-check the set before calling and skip the filter when null
- Initialize the collection to an empty Set and only call the method when non-empty
- Ensure the upstream code path that should populate the set actually runs
- Use planItemInstanceCaseInstanceId for a single id instead of a set
Example fix
// before
query.planItemInstanceCaseInstanceIds(ids).list();
// after
if (ids != null && !ids.isEmpty()) {
query.planItemInstanceCaseInstanceIds(ids);
}
List<HistoricPlanItemInstance> results = query.list(); Defensive patterns
Strategy: validation
Validate before calling
if (ids != null && !ids.isEmpty()) {
query.planItemInstanceCaseInstanceIds(ids);
} Type guard
boolean isUsableIdSet(Set<String> s) { return s != null && !s.isEmpty(); } Try / catch
try {
query.planItemInstanceCaseInstanceIds(ids);
} catch (FlowableIllegalArgumentException e) {
if (!e.getMessage().contains("Set of case instance ids is null")) throw e;
// fall back to unfiltered query or return empty result
} Prevention
- Initialize id collections eagerly; never leave them null
- Only call collection-filter methods when the collection is non-null and non-empty
- Validate collections at the boundary before building queries
When it happens
Trigger: Calling planItemInstanceCaseInstanceIds(null), often from a map lookup or variable initialized to null instead of an empty/collection value.
Common situations: Passing the result of a cache/config lookup that returned null; framework deserializers producing null for absent list parameters.
Related errors
- tenant id is null
- Plan item definition type is null
- Plan item definition types is null
- EntryCriterionId is null
- Case instance id is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/d96826b8ec292394.
Report an issue: GitHub.