flowable/flowable-engine · error · ActivitiIllegalArgumentException
A process instance id is required, but the provided id '" +…
Error message
A process instance id is required, but the provided id '" + processInstanceId + "' points to a child execution of process instance '" + processInstance.getProcessInstanceId() + "'. Please invoke the " + getClass().getSimpleName() + " with a root execution id.
What it means
findExecutionById can return a child (concurrent or scope) execution rather than the root. Because the command must operate on the process instance as a whole, it checks isProcessInstanceType() and throws ActivitiIllegalArgumentException when the id points to a child execution, telling the caller to use the root execution id.
Solutions
- Use processInstance.getProcessInstanceId() (available on the child execution) as the id — that is always the root.
- Query with runtimeService.createProcessInstanceQuery().processInstanceId(...) instead of createExecutionQuery() to obtain root ids.
- In listeners, use delegateExecution.getProcessInstanceId(), not getExecutionId().
Example fix
// before runtimeService.setProcessDefinitionVersion(execution.getId(), newVersion); // child execution // after runtimeService.setProcessDefinitionVersion(execution.getProcessInstanceId(), newVersion);
Defensive patterns
Strategy: validation
Validate before calling
String rootId = execution.isProcessInstanceType() ? execution.getId() : execution.getProcessInstanceId();
Type guard
boolean isRootExecution(Execution e) { return e.isProcessInstanceType(); } Try / catch
try {
runtimeService.setProcessDefinitionVersion(pid, version);
} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {
// pid was a child execution; resolve root and retry
} Prevention
- Use getProcessInstanceId(), never getExecutionId(), when an instance id is needed
- Query ProcessInstanceQuery instead of ExecutionQuery for instance-level operations
When it happens
Trigger: Passing an execution id (e.g. from an ExecutionQuery, a task's executionId, or an event listener on a concurrent branch) into setProcessDefinitionVersion instead of the process instance id.
Common situations: Code that stores executionId from a DelegateExecution in a parallel/multi-instance branch and later uses it as an instance id; migration scripts iterating executions rather than process instances.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- A process instance id is required, but the provided id
- Cannot use taskIds together with excludeLocalVariables
- caseInstanceId is null
- processInstanceId is null
- The business key is mandatory, but 'null' has been provided.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/530f9454f22edf28.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/SetProcessDefinitionVersionCmd.java:82
throw new ActivitiIllegalArgumentException("The process definition version is mandatory, but 'null' has been provided.");
}
if (processDefinitionVersion < 1) {
throw new ActivitiIllegalArgumentException("The process definition version must be positive, but '" + processDefinitionVersion + "' has been provided.");
}
this.processInstanceId = processInstanceId;
this.processDefinitionVersion = processDefinitionVersion;
}
@Override
public Void execute(CommandContext commandContext) {
// check that the new process definition is just another version of the same
// process definition that the process instance is using
ExecutionEntityManager executionManager = commandContext.getExecutionEntityManager();
ExecutionEntity processInstance = executionManager.findExecutionById(processInstanceId);
if (processInstance == null) {
throw new ActivitiObjectNotFoundException("No process instance found for id = '" + processInstanceId + "'.", ProcessInstance.class);
} else if (!processInstance.isProcessInstanceType()) {
throw new ActivitiIllegalArgumentException(
"A process instance id is required, but the provided id " +
"'" + processInstanceId + "' " +
"points to a child execution of process instance " +
"'" + processInstance.getProcessInstanceId() + "'. " +
"Please invoke the " + getClass().getSimpleName() + " with a root execution id.");
}
ProcessDefinitionImpl currentProcessDefinitionImpl = processInstance.getProcessDefinition();
DeploymentManager deploymentCache = commandContext
.getProcessEngineConfiguration()
.getDeploymentManager();
ProcessDefinition currentProcessDefinition = null;
if (currentProcessDefinitionImpl instanceof ProcessDefinitionEntity) {
currentProcessDefinition = (ProcessDefinitionEntity) currentProcessDefinitionImpl;
} else {
currentProcessDefinition = deploymentCache.findDeployedProcessDefinitionById(currentProcessDefinitionImpl.getId());
}
View on GitHub (pinned to d6d39ce1c6)