flowable/flowable-engine · error · FlowableIllegalArgumentException
Cannot throw process-instance scoped signal, since the dispa
Error message
Cannot throw process-instance scoped signal, since the dispatched event is not part of an ongoing process instance
What it means
SignalThrowingEventListener.onEvent throws this FlowableIllegalArgumentException when a signal is configured with processInstanceScope=true but the dispatched engine event has a null processInstanceId, so a process-instance-scoped signal cannot be delivered.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/SignalThrowingEventListener.java:46
import org.flowable.eventsubscription.service.impl.persistence.entity.SignalEventSubscriptionEntity;
/**
* An {@link FlowableEventListener} that throws a signal event when an event is dispatched to it.
*
* @author Frederik Heremans
*
*/
public class SignalThrowingEventListener extends BaseDelegateEventListener {
protected String signalName;
protected boolean processInstanceScope = true;
@Override
public void onEvent(FlowableEvent event) {
if (isValidEvent(event) && event instanceof FlowableEngineEvent engineEvent) {
if (engineEvent.getProcessInstanceId() == null && processInstanceScope) {
throw new FlowableIllegalArgumentException("Cannot throw process-instance scoped signal, since the dispatched event is not part of an ongoing process instance");
}
CommandContext commandContext = Context.getCommandContext();
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
EventSubscriptionService eventSubscriptionService = processEngineConfiguration.getEventSubscriptionServiceConfiguration().getEventSubscriptionService();
List<SignalEventSubscriptionEntity> subscriptionEntities = null;
if (processInstanceScope) {
subscriptionEntities = eventSubscriptionService.findSignalEventSubscriptionsByProcessInstanceAndEventName(engineEvent.getProcessInstanceId(), signalName);
} else {
String tenantId = null;
if (engineEvent.getProcessDefinitionId() != null) {
ProcessDefinition processDefinition = processEngineConfiguration.getDeploymentManager()
.findDeployedProcessDefinitionById(engineEvent.getProcessDefinitionId());
tenantId = processDefinition.getTenantId();
}
subscriptionEntities = eventSubscriptionService.findSignalEventSubscriptionsByEventName(signalName, tenantId);
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Register the listener only for event types that carry a processInstanceId, or add a wrapper listener that filters on event.getProcessInstanceId() != null.
- If the signal should be global (all process instances), set processInstanceScope=false so the execution-scoped branch is used.
- Trigger the signal via runtimeService.signalEventReceived with explicit delivery semantics if a specific subscription is targeted.
- Audit listener XML config: ensure 'scope' attribute matches the events the listener is bound to.
Example fix
// before <flowable:event-listener events="*" class="SignalThrowingEventListener" scope="processInstance" /> // after <flowable:event-listener events="ACTIVITY_SIGNAL_WAITING,JOB_EXECUTION_SUCCESS" class="SignalThrowingEventListener" scope="processInstance" />
Defensive patterns
Strategy: type-guard
Validate before calling
if (processInstanceScope && (event == null || !(event instanceof FlowableEngineEvent)
|| ((FlowableEngineEvent) event).getProcessInstanceId() == null)) {
throw new IllegalArgumentException("process-scoped signal requires an engine event with processInstanceId");
} Type guard
static boolean supportsProcessScopeSignal(FlowableEvent event) {
return event instanceof FlowableEngineEvent && ((FlowableEngineEvent) event).getProcessInstanceId() != null;
} Try / catch
try {
listener.onEvent(event);
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().contains("process-instance scoped signal")) {
logger.warn("ignored process-scoped signal for event {}", event.getType());
}
} Prevention
- Set scope=false for signals intended to reach all instances.
- Bind process-scoped signal listeners only to events that carry a processInstanceId.
- Review listener XML scope attributes whenever event bindings change.
When it happens
Trigger: A 'signal' event listener with processInstanceScope=true receives a FlowableEngineEvent whose getProcessInstanceId() is null — engine/deployment-level events, or events fired outside a running process instance.
Common situations: Global listeners reacting to all FlowableEventType values including engine events; signals thrown on process-start events before the instance id is assigned (rare) or on job/entity events outside process scope; copy-pasted listener config where scope was changed to process-instance but event source wasn't.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Cannot throw process-instance scoped message, since the disp
- No execution context active and event (" + event + ") is not
- Cannot create an event-throwing event-listener, unknown impl
- Unsupported entity-type for a FlowableEventListener: " + ent
- Could not handle signal: process definition with id: " + pro
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0118ac524cd1dfe7.
Report an issue: GitHub.