flowable/flowable-engine · error · FlowableException

Invalid signal handling: no execution nor process definition

Error message

Invalid signal handling: no execution nor process definition set for " + eventSubscription

What it means

A signal event subscription must be bound either to an execution (intermediate signal catch) or to a process definition (signal start event), or to a CMMN case scope. This error means the EventSubscription had neither an execution id, nor a process definition id, nor a matching CMMN scope — i.e. the subscription is orphaned or of an unhandled type.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/event/SignalEventHandler.java:72

            if (processDefinition.isSuspended()) {
                throw new FlowableException("Could not handle signal: process definition with id: " + processDefinitionId + " is suspended for " + eventSubscription);
            }

            // Start process instance via the flow element linked to the event
            FlowElement flowElement = process.getFlowElement(eventSubscription.getActivityId(), true);
            if (flowElement == null) {
                throw new FlowableException("Could not find matching FlowElement for " + eventSubscription);
            }

            ProcessInstanceHelper processInstanceHelper = CommandContextUtil.getProcessEngineConfiguration(commandContext).getProcessInstanceHelper();
            processInstanceHelper.createAndStartProcessInstanceWithInitialFlowElement(processDefinition, null, null, null, flowElement, process,
                    getPayloadAsMap(payload), null, null, null, true);

        } else if (eventSubscription.getScopeId() != null && ScopeTypes.CMMN.equals(eventSubscription.getScopeType())) {
            CommandContextUtil.getProcessEngineConfiguration(commandContext).getCaseInstanceService().handleSignalEvent(eventSubscription, getPayloadAsMap(payload));
        
        } else {
            throw new FlowableException("Invalid signal handling: no execution nor process definition set for " + eventSubscription);
        }
    }

    protected Map<String, Object> getPayloadAsMap(Object payload) {
        Map<String, Object> variables = null;
        if (payload instanceof Map) {
            variables = (Map<String, Object>) payload;
        }
        return variables;
    }

}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect ACT_RU_EVENT_SUBSCR for the subscription: fill in or remove the row if it is orphaned.
  2. Ensure the signal is routed through runtimeService.createSignalEvent(signalName)...send() rather than manually crafted subscription handling.
  3. If a custom scope type is used, register an appropriate event handler; the BPM SignalEventHandler only handles execution-, process-definition- and CMMN-scoped signals.
  4. Reproduce with the subscription id and file a Flowable issue if the data is consistent.

Example fix

// before
runtimeService.signalEventReceived(sub.getEventName(), sub.getId()); // subscription has no execution/definition
// after
EventSubscription sub = runtimeService.createEventSubscriptionQuery()
    .subscriptionId(id).singleResult();
if (sub != null && sub.getExecutionId() == null && sub.getProcessDefinitionId() == null) {
    runtimeService.deleteEventSubscription(id); // cleanup orphan before re-signaling
}
Defensive patterns

Strategy: validation

Validate before calling

EventSubscription sub = runtimeService.createEventSubscriptionQuery().subscriptionId(id).singleResult();
if (sub == null || (sub.getExecutionId() == null && sub.getProcessDefinitionId() == null
        && (sub.getScopeId() == null || !"cmmn".equals(sub.getScopeType())))) {
    throw new IllegalStateException("Orphaned signal subscription: " + id);
}

Try / catch

try {
    runtimeService.signalEventReceived(signalName, subscriptionId);
} catch (FlowableException e) {
    if (e.getMessage().startsWith("Invalid signal handling")) {
        runtimeService.deleteEventSubscription(subscriptionId);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling signalEventReceived for an EventSubscriptionEntity with null executionId, null processDefinitionId, and a scopeId/scopeType combination that is not CMMN — e.g. corrupted ACT_RU_EVENT_SUBSCR rows or custom/unknown scope types.

Common situations: Direct manipulation/migration of the runtime tables, plugins registering custom scope types the BPM signal handler does not know, partially deleted process instances leaving orphaned subscriptions.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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