flowable/flowable-engine · error · ActivitiObjectNotFoundException
execution " + executionId + " doesn't exist
Error message
execution " + executionId + " doesn't exist
What it means
Thrown by NeedsActiveExecutionCmd.execute() when no execution entity exists for the given executionId. The engine looks up the execution via findExecutionById and, since Activiti/Flowable cannot operate on a non-existent execution, it raises ActivitiObjectNotFoundException carrying the expected Execution class. It is a lookup failure, not a state or permission problem.
Solutions
- Verify the executionId exists before invoking: create an ExecutionQuery via runtimeService.createExecutionQuery().executionId(id).singleResult() and check for null.
- Confirm you are connected to the same process engine/database where the execution lives (check database schema and engine configuration).
- Check whether the process instance already completed or was deleted; fetch a fresh executionId from the current process instance instead of a cached one.
- Log/correct the source of the id (message correlation, signal payload) to rule out typo or truncation.
Example fix
// before
runtimeService.signal(executionId);
// after
Execution execution = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (execution != null) {
runtimeService.signal(executionId);
} Defensive patterns
Strategy: validation
Validate before calling
Execution e = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (e == null) throw new IllegalArgumentException("execution not found: " + executionId); Type guard
boolean executionExists(String id) {
return id != null && runtimeService.createExecutionQuery().executionId(id).singleResult() != null;
} Try / catch
try {
runtimeService.signal(executionId);
} catch (ActivitiObjectNotFoundException e) {
// execution gone; treat as already finished
} Prevention
- Query execution existence before operating on it
- Never cache executionIds across transactions that may complete the instance
- Confirm engine/datasource configuration points at the right database
When it happens
Trigger: Calling any command extending NeedsActiveExecutionCmd (e.g. signal, message event reception, execution-related runtime operations) with an executionId that has been deleted, was never created, is from a different engine/process instance, or contains a typo.
Common situations: Holding an executionId after the process instance ended and its executions were removed; pointing at an executionId from another process engine or database schema; reusing stale ids cached in application code after a DB cleanup/redeploy of the app.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Cannot find task with id " + taskId
- Candidate group is null
- Candidate group list is empty
- Candidate group list is empty
- Candidate group list is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/3758246a4cbf1780.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/NeedsActiveExecutionCmd.java:49
protected String executionId;
public NeedsActiveExecutionCmd(String executionId) {
this.executionId = executionId;
}
@Override
public T execute(CommandContext commandContext) {
if (executionId == null) {
throw new ActivitiIllegalArgumentException("executionId is null");
}
ExecutionEntity execution = commandContext
.getExecutionEntityManager()
.findExecutionById(executionId);
if (execution == null) {
throw new ActivitiObjectNotFoundException("execution " + executionId + " doesn't exist", Execution.class);
}
if (execution.isSuspended()) {
throw new ActivitiException(getSuspendedExceptionMessage());
}
return execute(commandContext, execution);
}
/**
* Subclasses should implement this method. The provided {@link ExecutionEntity} is guaranteed to be active (ie. not suspended).
*/
protected abstract T execute(CommandContext commandContext, ExecutionEntity execution);
/**
* Subclasses can override this to provide a more detailed exception message that will be thrown when the execution is suspended.
*/
protected String getSuspendedExceptionMessage() {View on GitHub (pinned to d6d39ce1c6)