flowable/flowable-engine · error · FlowableObjectNotFoundException

Cannot find execution with id

Error message

Cannot find execution with id '${executionId}'

What it means

Lookup failure in SignalEventReceivedCmd.execute: the command was given a specific executionId to deliver a signal to, but no execution with that id exists (finished, deleted, or wrong id), so the signal event subscription cannot be triggered.

Solutions

  1. Verify the execution still exists with runtimeService.createExecutionQuery().executionId(executionId).singleResult() before signaling.
  2. Make signal delivery idempotent: treat 'execution not found' as 'already continued' and skip instead of failing.
  3. Fix the source of the id so a valid, live executionId is captured when the execution starts waiting.

Example fix

// before
runtimeService.signalEventReceived("orderPaid", executionId);
// after
Execution e = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (e != null) runtimeService.signalEventReceived("orderPaid", executionId);
Defensive patterns

Strategy: validation

Validate before calling

Execution e = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (e != null) runtimeService.signalEventReceived(signalName, executionId);

Try / catch

try {
    runtimeService.signalEventReceived(signalName, executionId);
} catch (FlowableObjectNotFoundException e) {
    log.info("Execution {} already gone; treating signal as consumed", executionId);
}

Prevention

When it happens

Trigger: Calling runtimeService.signalEventReceived(signalName, executionId) with an executionId that was deleted, already ended, or never existed.

Common situations: Signals delivered from external systems after the waiting process step already completed or was terminated; stale execution ids persisted by the caller; racing deliveries where the execution ends between query and signal.

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/25dcff3824433a67. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/SignalEventReceivedCmd.java:83

        this.payload = null;
        this.tenantId = tenantId;
    }

    @Override
    public Void execute(CommandContext commandContext) {

        List<SignalEventSubscriptionEntity> signalEvents = null;

        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        EventSubscriptionService eventSubscriptionService = processEngineConfiguration.getEventSubscriptionServiceConfiguration().getEventSubscriptionService();
        if (executionId == null) {
            signalEvents = eventSubscriptionService.findSignalEventSubscriptionsByEventName(eventName, tenantId);
        } else {

            ExecutionEntity execution = CommandContextUtil.getExecutionEntityManager(commandContext).findById(executionId);

            if (execution == null) {
                throw new FlowableObjectNotFoundException("Cannot find execution with id '" + executionId + "'", Execution.class);
            }

            if (execution.isSuspended()) {
                throw new FlowableException("Cannot throw signal event '" + eventName + "' because " + execution + " is suspended");
            }

            if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, execution.getProcessDefinitionId())) {
                Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler();
                compatibilityHandler.signalEventReceived(eventName, executionId, payload, async, tenantId);
                return null;
            }

            signalEvents = eventSubscriptionService.findSignalEventSubscriptionsByNameAndExecution(eventName, executionId);

            if (signalEvents.isEmpty()) {
                throw new FlowableException(execution + " has not subscribed to a signal event with name '" + eventName + "'.");
            }
        }

View on GitHub (pinned to d6d39ce1c6)