flowable/flowable-engine · error · ActivitiObjectNotFoundException
Cannot find execution with id
Error message
Cannot find execution with id '<executionId>'
What it means
SignalEventReceivedCmd throws ActivitiObjectNotFoundException when no execution entity matches the supplied executionId while delivering a signal to a specific execution. Without a live execution the engine cannot inject the signal event, so it aborts with Execution.class as the missing type.
Solutions
- Re-query before signaling: runtimeService.createExecutionQuery().executionId(id).list() and only signal when non-empty.
- Handle ActivitiObjectNotFoundException and treat it as 'signal no longer applicable' rather than a failure.
- Signal the process instance via correlation or signalEventReceived(name) without execution targeting if scope tracking is unreliable.
Example fix
// before
runtimeService.signalEventReceived("order-approved", executionId);
// after
Execution exec = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (exec != null) {
runtimeService.signalEventReceived("order-approved", executionId);
} Defensive patterns
Strategy: validation
Validate before calling
boolean live = runtimeService.createExecutionQuery().executionId(executionId).count() > 0; if (live) runtimeService.signalEventReceived(eventName, executionId);
Try / catch
try {
runtimeService.signalEventReceived(eventName, executionId);
} catch (ActivitiObjectNotFoundException e) {
logger.info("Execution {} gone; signal {} discarded as stale", executionId, eventName);
} Prevention
- Re-fetch the execution immediately before signaling; async continuations can consume it in between.
- Design event handlers to treat missing executions as benign no-ops.
- Avoid caching execution IDs across long intervals.
When it happens
Trigger: Calling runtimeService.signalEventReceived(signalName, executionId) with an executionId that no longer exists in ACT_RU_EXECUTION (consumed, scope destroyed, or instance finished).
Common situations: Execution already continued past the signal-catching state; process instance finished before the signal arrived; ID captured earlier and reused after an async boundary completed.
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 throw signal event
- Execution ' ' has not subscribed to a signal event with…
- A delegated task cannot be completed, but should be…
- Can not activate job
- Cannot find execution with id
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/af2b4bb90d58cb45.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/SignalEventReceivedCmd.java:78
this.async = async;
this.payload = null;
this.tenantId = tenantId;
}
@Override
public Void execute(CommandContext commandContext) {
List<SignalEventSubscriptionEntity> signalEvents = null;
if (executionId == null) {
signalEvents = commandContext.getEventSubscriptionEntityManager().findSignalEventSubscriptionsByEventName(eventName, tenantId);
} else {
ExecutionEntity execution = commandContext.getExecutionEntityManager().findExecutionById(executionId);
if (execution == null) {
throw new ActivitiObjectNotFoundException("Cannot find execution with id '" + executionId + "'", Execution.class);
}
if (execution.isSuspended()) {
throw new ActivitiException("Cannot throw signal event '" + eventName
+ "' because execution '" + executionId + "' is suspended");
}
signalEvents = commandContext.getEventSubscriptionEntityManager().findSignalEventSubscriptionsByNameAndExecution(eventName, executionId);
if (signalEvents.isEmpty()) {
throw new ActivitiException("Execution '" + executionId + "' has not subscribed to a signal event with name '" + eventName + "'.");
}
}
for (SignalEventSubscriptionEntity signalEventSubscriptionEntity : signalEvents) {
// We only throw the event to globally scoped signals.
// Process instance scoped signals must be thrown within the process itself
if (signalEventSubscriptionEntity.isGlobalScoped()) {
View on GitHub (pinned to d6d39ce1c6)