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

  1. Re-query before signaling: runtimeService.createExecutionQuery().executionId(id).list() and only signal when non-empty.
  2. Handle ActivitiObjectNotFoundException and treat it as 'signal no longer applicable' rather than a failure.
  3. 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

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


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)