flowable/flowable-engine · error · FlowableIllegalArgumentException
A dynamically created plan item can only be injected into a…
Error message
A dynamically created plan item can only be injected into a running stage instance or case instance.
What it means
Thrown when the PlanItemInstanceBuilder specifies neither a running stage instance nor a case instance to inject into (injectInCase() is false but no stage instance was set). Dynamic plan items must be attached to an active stage or case instance so the engine knows the parent scope and case definition; neither being set is an invalid builder configuration.
Solutions
- Call planItemInstanceBuilder.injectInCase() with a valid, running case instance id when injecting at case level.
- Or set the target stage instance for injection into a running stage; confirm the stage is in active state.
- Check builder wiring/order so either a stage instance or injectInCase is always configured before executing the command.
Example fix
// before
PlanItemInstance p = cmmnRuntimeService.createPlanItemInstanceBuilder()
.caseDefinitionId(defId).elementId(elementId).create(); // no parent scope
// after
PlanItemInstance p = cmmnRuntimeService.createPlanItemInstanceBuilder()
.caseDefinitionId(defId).elementId(elementId)
.injectInCase() // or .injectInStage(stageInstanceId)
.caseInstanceId(caseInstanceId)
.create(); Defensive patterns
Strategy: validation
Validate before calling
if (stageInstanceId == null && caseInstanceId == null) {
throw new IllegalArgumentException("Provide a running stage instance or call injectInCase with a caseInstanceId");
}
PlanItemInstanceEntityBuilder b = cmmnRuntimeService.createPlanItemInstanceBuilder()
.caseDefinitionId(defId).elementId(elementId);
if (stageInstanceId != null) {
b.injectInStage(stageInstanceId);
} else {
b.injectInCase().caseInstanceId(caseInstanceId);
} Prevention
- Always set a parent scope (stage instance or injectInCase + case instance id) on the builder.
- Verify the target case/stage instance is active before injecting.
When it happens
Trigger: Building a dynamic plan item via planItemInstanceBuilder without calling injectInCase() and without supplying a stage instance (e.g. stageInstanceId / planItemInstanceBuilder.injectInStage(...)), or supplying ids of instances that are not running.
Common situations: Forgetting to set the parent scope when constructing the builder programmatically; copying builder code that uses injectInCase but removing the case instance call; misordering builder calls so scope configuration is skipped.
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
- Cannot create 'script' task listener. Missing ScriptInfo.
- Cannot migrate case(es), not enough information
- Could not find case element with id
- Could not find case model with case definition id
- 'language' evaluated to null for taskListener of type…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/02f5844ee6ce038f.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/CreateInjectedPlanItemInstanceCmd.java:76
}
String runningCaseDefinitionId;
String caseInstanceId;
String tenantId;
PlanItemInstance stagePlanItemInstance = null;
if (planItemInstanceBuilder.injectInStage()) {
stagePlanItemInstance = getStageInstanceEntity(commandContext);
caseInstanceId = stagePlanItemInstance.getCaseInstanceId();
tenantId = stagePlanItemInstance.getTenantId();
runningCaseDefinitionId = stagePlanItemInstance.getCaseDefinitionId();
} else if (planItemInstanceBuilder.injectInCase()) {
CaseInstance caseInstance = getCaseInstanceEntity(commandContext);
caseInstanceId = caseInstance.getId();
tenantId = caseInstance.getTenantId();
runningCaseDefinitionId = caseInstance.getCaseDefinitionId();
} else {
throw new FlowableIllegalArgumentException("A dynamically created plan item can only be injected into a running stage instance or case instance.");
}
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
PlanItemInstanceEntity planItemInstanceEntity = cmmnEngineConfiguration.getPlanItemInstanceEntityManager()
.createPlanItemInstanceEntityBuilder()
.caseDefinitionId(runningCaseDefinitionId)
.derivedCaseDefinitionId(planItemInstanceBuilder.getCaseDefinitionId())
.planItem((PlanItem) caseElement)
.name(planItemInstanceBuilder.getName())
.caseInstanceId(caseInstanceId)
.stagePlanItemInstance(stagePlanItemInstance)
.tenantId(tenantId)
.addToParent(true)
.create();
// after adding the plan item to the stage, add it to the agenda for creation and afterwards for activation processing
CmmnEngineAgenda agenda = CommandContextUtil.getAgenda(commandContext);
agenda.planCreatePlanItemInstanceOperation(planItemInstanceEntity);View on GitHub (pinned to d6d39ce1c6)