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 '<processInstanceId>'. Please invoke the SetProcessInstanceBusinessKeyCmd with a root execution id.
What it means
As with the version-migration command, findExecutionById may return a non-root execution. When !processInstance.isProcessInstanceType() the command throws ActivitiIllegalArgumentException instructing the caller to invoke SetProcessInstanceBusinessKeyCmd with a root execution id, since the business key belongs to the process instance, not to a child execution.
Solutions
- Use the root id: execution.getProcessInstanceId() instead of execution.getId().
- Look up the instance via createProcessInstanceQuery() rather than createExecutionQuery().
- Store processInstanceId (not executionId) wherever the business key will be updated later.
Example fix
// before runtimeService.setBusinessKey(task.getExecutionId(), key); // may be a child execution // after runtimeService.setBusinessKey(task.getProcessInstanceId(), key);
Defensive patterns
Strategy: validation
Validate before calling
String rootId = execution.isProcessInstanceType() ? execution.getId() : execution.getProcessInstanceId(); runtimeService.setBusinessKey(rootId, key);
Type guard
boolean isRootExecution(Execution e) { return e.isProcessInstanceType(); } Try / catch
try {
runtimeService.setBusinessKey(pid, key);
} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {
// resolve root processInstanceId and retry
} Prevention
- Persist processInstanceId (not executionId) as your correlation reference
- Be aware parallel/multi-instance branches create child executions with distinct ids
When it happens
Trigger: Passing an executionId from an ExecutionQuery, DelegateExecution.getExecutionId() in a concurrent branch, or TaskEntity.getExecutionId() into runtimeService.setBusinessKey.
Common situations: Parallel gateways / multi-instance activities producing multiple executions; listeners capturing execution ids and reusing them as instance ids later.
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/c848439e6306e024.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/SetProcessInstanceBusinessKeyCmd.java:57
if (processInstanceId == null || processInstanceId.length() < 1) {
throw new ActivitiIllegalArgumentException("The process instance id is mandatory, but '" + processInstanceId + "' has been provided.");
}
if (businessKey == null) {
throw new ActivitiIllegalArgumentException("The business key is mandatory, but 'null' has been provided.");
}
this.processInstanceId = processInstanceId;
this.businessKey = businessKey;
}
@Override
public Void execute(CommandContext commandContext) {
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.");
}
processInstance.updateProcessBusinessKey(businessKey);
return null;
}
}
View on GitHub (pinned to d6d39ce1c6)