Activiti/Activiti · error · ActivitiObjectNotFoundException
No process instance found for id
Error message
No process instance found for id '${processInstanceId}' What it means
Activiti throws ActivitiObjectNotFoundException when deleteProcessInstance is given a processInstanceId that does not resolve to a process-instance execution. The entity manager findById returns null and the engine throws before attempting the cascade delete. It signals the instance never existed, already completed, or was already deleted.
Solutions
- Check existence first with runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult() and skip when null.
- Handle ActivitiObjectNotFoundException in the cleanup loop and treat it as success (idempotent deletion).
- Only attempt deletion of instances in a running state (query with .active() if applicable).
- Confirm the id is a process instance id (root execution), not a child execution id from another table/query.
Example fix
// before
runtimeService.deleteProcessInstance(instanceId, "cleanup"); // throws when already gone
// after
if (runtimeService.createProcessInstanceQuery().processInstanceId(instanceId).singleResult() != null) {
runtimeService.deleteProcessInstance(instanceId, "cleanup");
} Defensive patterns
Strategy: validation
Validate before calling
boolean running = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.count() > 0;
if (!running) log.info("Instance {} already ended/deleted, skipping delete", processInstanceId); Try / catch
try {
runtimeService.deleteProcessInstance(processInstanceId, reason);
} catch (org.activiti.engine.ActivitiObjectNotFoundException e) {
log.info("Process instance {} already gone", processInstanceId);
} Prevention
- Re-check instance existence immediately before delete in batch jobs
- Make cleanup loops idempotent by swallowing not-found exceptions
- Confirm ids come from ProcessInstanceQuery, not child executions
When it happens
Trigger: Calling runtimeService.deleteProcessInstance(id, reason) with an id from a finished instance, an already-deleted instance, or a mistyped/non-existent id (also internally from deleteProcessInstancesByProcessDefinition cascades).
Common situations: Cleanup jobs racing with instance completion; deleting instances that ended between listing and deleting; stale ids cached in application state; environment/database mismatch.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Cannot find process definition with id
- Cannot find process instance with id
- Cannot find process instance with id
- Cannot find processInstance for id '
- Could not find a deployment with id '
AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09).
Data as JSON: /api/errors/558ce4bff2de6022.
Report an issue: GitHub.
Appendix: source
Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/persistence/entity/ExecutionEntityManagerImpl.java:467
);
for (String processInstanceId : processInstanceIds) {
deleteProcessInstance(processInstanceId, deleteReason, cascade);
}
if (cascade) {
getHistoricProcessInstanceEntityManager().deleteHistoricProcessInstanceByProcessDefinitionId(
processDefinitionId
);
}
}
@Override
public void deleteProcessInstance(String processInstanceId, String deleteReason, boolean cascade) {
ExecutionEntity execution = findById(processInstanceId);
if (execution == null) {
throw new ActivitiObjectNotFoundException(
"No process instance found for id '" + processInstanceId + "'",
ProcessInstance.class
);
}
deleteProcessInstanceCascade(execution, deleteReason, cascade);
}
protected void deleteProcessInstanceCascade(ExecutionEntity execution, String deleteReason, boolean deleteHistory) {
// fill default reason if none provided
if (deleteReason == null) {
deleteReason = DeleteReason.PROCESS_INSTANCE_DELETED;
}
for (ExecutionEntity subExecutionEntity : execution.getExecutions()) {
if (subExecutionEntity.isMultiInstanceRoot()) {
for (ExecutionEntity miExecutionEntity : subExecutionEntity.getExecutions()) {
if (miExecutionEntity.getSubProcessInstance() != null) {View on GitHub (pinned to 56435b1a97)