flowable/flowable-engine · error · ActivitiException
The new process definition
Error message
The new process definition (key = '<key>') does not contain the current activity (id = '<activityId>') of the process instance (id = '<processInstanceId>').
What it means
validateAndSwitchVersionOfExecution verifies that every activity the execution is currently sitting in exists in the new process definition version (ProcessDefinitionEntity.contains). If the new version removed or renamed that activity, migrating would leave the instance pointing at a nonexistent flow element, so ActivitiException is thrown.
Solutions
- Keep removed activities as deprecated pass-through elements (or keep their ids stable) in the new BPMN version before migrating.
- Deploy a compatibility version of the diagram that still contains the missing activity id, migrate, then move the flow manually (changeActivityState / moveExecutionActivityIdTo on newer engines).
- Pick a target version that still contains the activity: inspect DeploymentManager/BpmnModel for the version before calling the command.
Example fix
// before // new version 3 of order.bpmn removed <userTask id="manualReview"> runtimeService.setProcessDefinitionVersion(pid, 3); // after // keep the element in version 3: <userTask id="manualReview" .../> (optionally behind a skip condition) runtimeService.setProcessDefinitionVersion(pid, 3);
Defensive patterns
Strategy: validation
Validate before calling
// verify the activity exists in the target version before migrating
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey(key).processDefinitionVersion(version).singleResult();
BpmnModel model = repositoryService.getBpmnModel(pd.getId());
boolean contains = model.getFlowElement(currentActivityId) != null
|| model.getMainProcess().getFlowElement(currentActivityId) != null; Try / catch
try {
runtimeService.setProcessDefinitionVersion(pid, version);
} catch (org.activiti.engine.ActivitiException e) {
if (e.getMessage() != null && e.getMessage().contains("does not contain the current activity")) {
// fall back to a compatible version or adjust the model
}
} Prevention
- Keep activity ids stable across BPMN versions
- Never remove activities from a definition while instances wait on them
- Diff successive BPMN versions before deploying breaking changes
When it happens
Trigger: runtimeService.setProcessDefinitionVersion(pid, v) where version v of the same key was deployed after deleting/renaming a BPMN activity (userTask/serviceTask id) that the instance is currently waiting in.
Common situations: Redeploying a changed BPMN model that removed a user task while instances were still waiting on it; renaming element ids across versions; migrating an instance stuck mid-branch of a deleted subprocess.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- A process instance id is required, but the provided id '" +…
- A process instance id is required, but the provided id
- activatedBefore is null
- activity tenant id is null
- after time is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/d44a48b3fc6ad808.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/SetProcessDefinitionVersionCmd.java:122
validateAndSwitchVersionOfExecution(commandContext, processInstance, newProcessDefinition);
// switch the historic process instance to the new process definition version
commandContext.getHistoryManager().recordProcessDefinitionChange(processInstanceId, newProcessDefinition.getId());
// switch all sub-executions of the process instance to the new process definition version
List<ExecutionEntity> childExecutions = executionManager
.findChildExecutionsByProcessInstanceId(processInstanceId);
for (ExecutionEntity executionEntity : childExecutions) {
validateAndSwitchVersionOfExecution(commandContext, executionEntity, newProcessDefinition);
}
return null;
}
protected void validateAndSwitchVersionOfExecution(CommandContext commandContext, ExecutionEntity execution, ProcessDefinitionEntity newProcessDefinition) {
// check that the new process definition version contains the current activity
if (execution.getActivity() != null && !newProcessDefinition.contains(execution.getActivity())) {
throw new ActivitiException(
"The new process definition " +
"(key = '" + newProcessDefinition.getKey() + "') " +
"does not contain the current activity " +
"(id = '" + execution.getActivity().getId() + "') " +
"of the process instance " +
"(id = '" + processInstanceId + "').");
}
// switch the process instance to the new process definition version
execution.setProcessDefinition(newProcessDefinition);
// and change possible existing tasks (as the process definition id is stored there too)
List<TaskEntity> tasks = commandContext.getTaskEntityManager().findTasksByExecutionId(execution.getId());
for (TaskEntity taskEntity : tasks) {
taskEntity.setProcessDefinitionId(newProcessDefinition.getId());
commandContext.getHistoryManager().recordTaskProcessDefinitionChange(taskEntity.getId(), newProcessDefinition.getId());
}
}View on GitHub (pinned to d6d39ce1c6)