flowable/flowable-engine · error · ActivitiException

Execution with id '" + executionId + "' does not have a…

Error message

Execution with id '" + executionId + "' does not have a subscription to a message event with name '" + messageName + "'

What it means

Thrown by MessageEventReceivedCmd.execute() when no message event subscription with the given messageName exists on the given execution. The engine queries event subscriptions by name+execution; an empty result means the execution is not waiting for that message, so delivery is impossible and ActivitiException is raised.

Solutions

  1. Use the execution id of the execution waiting in the message catch event (query createExecutionQuery().messageEventSubscriptionName(name))
  2. Verify the messageName exactly matches the BPMN messageRef/catch event name
  3. Use executionEntity.eventReceived semantics via runtimeService.trigger or an execution query to find valid targets
  4. Handle the race: catch ActivitiException and re-query before retrying delivery

Example fix

// before
runtimeService.messageEventReceived("orderMsg", processInstanceId);
// after
Execution e = runtimeService.createExecutionQuery()
    .messageEventSubscriptionName("orderMsg")
    .processInstanceId(processInstanceId).singleResult();
if (e != null) runtimeService.messageEventReceived("orderMsg", e.getId());
Defensive patterns

Strategy: validation

Validate before calling

Execution e = runtimeService.createExecutionQuery().messageEventSubscriptionName(messageName).executionId(executionId).singleResult();
if (e == null) throw new IllegalStateException("no subscription for " + messageName);

Try / catch

try { runtimeService.messageEventReceived(messageName, executionId, payload); } catch (ActivitiException e) { if (e.getMessage().contains("does not have a subscription")) { log.warn("message not awaited; process may have moved on"); return; } throw e; }

Prevention

When it happens

Trigger: runtimeService.messageEventReceived(name, executionId) where the execution has no active message boundary/intermediate catch event with that name; wrong execution id (e.g. passing process instance id instead of the waiting execution id); message already consumed or event fired before delivery.

Common situations: Correlation code using processInstanceId instead of the execution id of the scope waiting for the message; race between two triggers; process advanced past the catch event before delivery; message name mismatch with the BPMN messageRef.

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/905aab1ede7d56c6. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/MessageEventReceivedCmd.java:74

    public MessageEventReceivedCmd(String messageName, String executionId, boolean async) {
        super(executionId);
        this.messageName = messageName;
        this.payload = null;
        this.async = async;
    }

    @Override
    protected Void execute(CommandContext commandContext, ExecutionEntity execution) {
        if (messageName == null) {
            throw new ActivitiIllegalArgumentException("messageName cannot be null");
        }

        List<EventSubscriptionEntity> eventSubscriptions = commandContext.getEventSubscriptionEntityManager()
                .findEventSubscriptionsByNameAndExecution(MessageEventHandler.EVENT_HANDLER_TYPE, messageName, executionId);

        if (eventSubscriptions.isEmpty()) {
            throw new ActivitiException("Execution with id '" + executionId + "' does not have a subscription to a message event with name '" + messageName + "'");
        }

        // there can be only one:
        EventSubscriptionEntity eventSubscriptionEntity = eventSubscriptions.get(0);

        eventSubscriptionEntity.eventReceived(payload, async);

        return null;
    }

}

View on GitHub (pinned to d6d39ce1c6)