flowable/flowable-engine · error · FlowableIllegalArgumentException
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 ${class simple name} with a root execution id. What it means
Thrown by execute() when the given id resolves to an execution, but that execution is a child execution rather than the root process-instance execution. Business key is stored on the root execution, so Flowable refuses to set it on a child and points you at the correct root id.
Solutions
- Use processInstance.getId() / execution.getProcessInstanceId() (root id) instead of the child execution id.
- If you only have an Execution, call execution.getProcessInstanceId() to get the root and pass that.
- Query RuntimeService.createProcessInstanceQuery().processInstanceId(...) to confirm the id is of process instance type.
Example fix
// before runtimeService.setProcessInstanceBusinessKey(task.getExecutionId(), key); // after runtimeService.setProcessInstanceBusinessKey(task.getProcessInstanceId(), key);
Defensive patterns
Strategy: type-guard
Validate before calling
ProcessInstance pi = runtimeService.createProcessInstanceQuery()
.processInstanceId(candidateId).singleResult();
boolean isRoot = pi != null && candidateId.equals(pi.getId()); Type guard
boolean isProcessInstanceRoot(String id, RuntimeService rs) {
ProcessInstance pi = rs.createProcessInstanceQuery().processInstanceId(id).singleResult();
return pi != null && pi.getProcessInstanceId() == null || (pi != null && id.equals(pi.getId()));
} Try / catch
try {
runtimeService.setProcessInstanceBusinessKey(id, key);
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().contains("points to a child execution")) {
// switch to execution.getProcessInstanceId() and retry
}
} Prevention
- Always use ProcessInstance.getId()/getProcessInstanceId(), never Task/child execution ids.
- In delegates, use DelegateExecution.getProcessInstanceId().
- Remember sub-processes and call activities create child executions with different ids.
When it happens
Trigger: Calling RuntimeService.setProcessInstanceBusinessKey with an execution id obtained from a task's getExecutionId() (which is usually a child/scope execution), not from ProcessInstance.getId().
Common situations: Developers inside a delegate/task listener use DelegateExecution.getId() or Task.getExecutionId() and pass that as a process instance id; scope executions (embedded sub-processes, call activities) frequently differ from the root id.
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
- ProcessInstanceId cannot be null.
- ProcessInstanceId cannot be null.
- processInstanceId is null
- processInstanceId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/e26c3b2a2cfaa695.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/SetProcessInstanceBusinessKeyCmd.java:66
this.processInstanceId = processInstanceId;
this.businessKey = businessKey;
}
@Override
public Void execute(CommandContext commandContext) {
ExecutionEntityManager executionManager = CommandContextUtil.getExecutionEntityManager(commandContext);
ExecutionEntity processInstance = executionManager.findById(processInstanceId);
if (processInstance == null) {
if (CommandContextUtil.getProcessEngineConfiguration(commandContext).isFlowable5CompatibilityEnabled()) {
CommandContextUtil.getProcessEngineConfiguration(commandContext).getFlowable5CompatibilityHandler().updateBusinessKey(processInstanceId,
businessKey);
return null;
}
throw new FlowableObjectNotFoundException("No process instance found for id = '" + processInstanceId + "'.", ProcessInstance.class);
} else if (!processInstance.isProcessInstanceType()) {
throw new FlowableIllegalArgumentException("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.");
}
if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, processInstance.getProcessDefinitionId())) {
CommandContextUtil.getProcessEngineConfiguration(commandContext).getFlowable5CompatibilityHandler().updateBusinessKey(processInstanceId, businessKey);
return null;
}
executionManager.updateProcessInstanceBusinessKey(processInstance, businessKey);
return null;
}
}
View on GitHub (pinned to d6d39ce1c6)