flowable/flowable-engine · error · FlowableIllegalArgumentException
selectCaseInstanceEagerFetchPlanItemInstances needs either…
Error message
selectCaseInstanceEagerFetchPlanItemInstances needs either caseInstanceId or planItemInstanceId
What it means
Thrown by MybatisCaseInstanceDataManagerImpl.findCaseInstanceEntityEagerFetchPlanItemInstances when neither caseInstanceId nor planItemInstanceId was supplied. The eager-fetch query needs at least one of these parameters to identify which case instance to load with its plan item instances.
Solutions
- Pass a non-null caseInstanceId or planItemInstanceId to findById
- Ensure the calling code actually resolved one of the two identifiers before doing the eager fetch
Example fix
// before caseInstanceEntityManager.findById(null, null); // after caseInstanceEntityManager.findById(caseInstanceId, null);
Defensive patterns
Strategy: validation
Validate before calling
if (caseInstanceId == null && planItemInstanceId == null) {
throw new IllegalArgumentException("Either caseInstanceId or planItemInstanceId is required");
} Type guard
boolean hasIdentifier = caseInstanceId != null || planItemInstanceId != null;
Try / catch
try {
return dataManager.findCaseInstanceEntityEagerFetchPlanItemInstances(caseInstanceId, planItemInstanceId);
} catch (FlowableIllegalArgumentException e) {
// resolve an identifier from the caller context first
} Prevention
- Resolve at least one identifier before doing eager fetches
- Keep upstream code from silently propagating null ids
- Unit-test data manager helpers with null-argument cases
When it happens
Trigger: Calling findById(null, null) (or equivalent) on the case instance data manager with both parameters null.
Common situations: Custom engine extensions that pass through null values from an upper layer; refactored code where one of the two identifiers became null due to an upstream bug.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Business status is null
- callback type is null
- callbackIds is null or empty
- Case definition keys is null
- caseInstance tenant id is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/447167050801ea50.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/persistence/entity/data/impl/MybatisCaseInstanceDataManagerImpl.java:91
public CaseInstanceEntity findCaseInstanceEntityEagerFetchPlanItemInstances(String caseInstanceId, String planItemInstanceId) {
// Could have been fetched before
EntityCache entityCache = getEntityCache();
CaseInstanceEntity cachedCaseInstanceEntity = entityCache.findInCache(getManagedEntityClass(), caseInstanceId);
if (cachedCaseInstanceEntity != null) {
return cachedCaseInstanceEntity;
}
// Not in cache
HashMap<String, Object> params = new HashMap<>(1);
if (caseInstanceId != null) {
params.put("caseInstanceId", caseInstanceId);
} else if (planItemInstanceId != null) {
params.put("planItemInstanceId", planItemInstanceId);
}
if (params.isEmpty()) {
throw new FlowableIllegalArgumentException("selectCaseInstanceEagerFetchPlanItemInstances needs either caseInstanceId or planItemInstanceId");
}
// The case instance will be fetched and will have all plan item instances in the childPlanItemInstances property.
// Those children need to be properly moved to the correct parent
CaseInstanceEntityImpl caseInstanceEntity = (CaseInstanceEntityImpl) getDbSqlSession().selectOne("selectCaseInstanceEagerFetchPlanItemInstances", params);
if (caseInstanceEntity != null) {
List<PlanItemInstanceEntity> allPlanItemInstances = caseInstanceEntity.getChildPlanItemInstances();
ArrayList<PlanItemInstanceEntity> directPlanItemInstances = new ArrayList<>();
HashMap<String, PlanItemInstanceEntity> planItemInstanceMap = new HashMap<>(allPlanItemInstances.size());
// Map all plan item instances to its id
for (PlanItemInstanceEntity planItemInstanceEntity : allPlanItemInstances) {
PlanItemInstanceEntity currentPlanItemInstanceEntity = planItemInstanceEntity;
// If it's already in the cache, it has precedence on the fetched one
PlanItemInstanceEntity planItemInstanceFromCache = entityCache.findInCache(PlanItemInstanceEntityImpl.class, planItemInstanceEntity.getId());View on GitHub (pinned to d6d39ce1c6)