flowable/flowable-engine · error · FlowableObjectNotFoundException
execution " + executionId + " doesn't exist
Error message
execution " + executionId + " doesn't exist
What it means
Flowable throws FlowableObjectNotFoundException when a command that requires an active execution cannot find the execution entity for the given executionId in the ACT_RU_EXECUTION table. The lookup happens in NeedsActiveExecutionCmd.execute before delegating to the concrete command, so any subclass command (e.g. signal, trigger, message event) on a stale or wrong execution id fails here.
Solutions
- Verify the executionId exists: query RuntimeService.createExecutionQuery().executionId(id).singleResult() before invoking the command.
- Re-fetch the execution id from a fresh process instance rather than reusing ids from a previous run or a completed instance.
- Confirm the app connects to the same database/schema where the process instance was started (check flowable datasource config).
- Catch FlowableObjectNotFoundException and surface a 404-style message to the caller instead of a 500.
Example fix
// before
runtimeService.trigger("unknown-exec-id");
// after
Execution execution = runtimeService.createExecutionQuery().executionId("unknown-exec-id").singleResult();
if (execution != null) {
runtimeService.trigger(execution.getId());
} Defensive patterns
Strategy: validation
Validate before calling
Execution exec = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (exec == null) { throw new NotFoundException("Execution " + executionId + " not found"); } Type guard
boolean executionExists(String id) {
return id != null && runtimeService.createExecutionQuery().executionId(id).count() > 0;
} Try / catch
try {
runtimeService.trigger(executionId);
} catch (FlowableObjectNotFoundException e) {
log.warn("Execution {} no longer exists", executionId, e);
throw new NotFoundException(e.getMessage());
} Prevention
- Always resolve execution ids from a fresh ExecutionQuery, never cache them across sessions.
- Distinguish processInstanceId from executionId in your domain model.
- Verify datasource points at the intended Flowable schema in each environment.
- Map FlowableObjectNotFoundException to a 404 in REST layers.
When it happens
Trigger: Calling a NeedsActiveExecutionCmd subclass (e.g. TriggerExecutionCmd, ExecutionSignalCmd) via RuntimeService/ExecutionService with an executionId that does not exist in the database.
Common situations: Using an execution id from a completed or deleted process instance; passing a processInstanceId instead of an execution id after restart; stale ids cached in client code across test runs; cluster with separate databases.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- No execution found for id
- Cannot associate execution by id: no execution with id '
- Cannot find execution with id
- Cannot find process instance with id
- Cannot find process instance with id
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/cf34d66c305e03c5.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/NeedsActiveExecutionCmd.java:48
private static final long serialVersionUID = 1L;
protected String executionId;
public NeedsActiveExecutionCmd(String executionId) {
this.executionId = executionId;
}
@Override
public T execute(CommandContext commandContext) {
if (executionId == null) {
throw new FlowableIllegalArgumentException("executionId is null");
}
ExecutionEntity execution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(executionId);
if (execution == null) {
throw new FlowableObjectNotFoundException("execution " + executionId + " doesn't exist", Execution.class);
}
if (execution.isSuspended()) {
throw new FlowableException(getSuspendedExceptionMessagePrefix() + " a suspended " + execution);
}
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 getSuspendedExceptionMessagePrefix() {View on GitHub (pinned to d6d39ce1c6)