{"record":{"id":"f3bb8c8fe1acb0c6","repo":"flowable/flowable-engine","slug":"cannot-throw-process-instance-scoped-message-sinc","errorCode":null,"errorMessage":"Cannot throw process-instance scoped message, since the dispatched event is not part of an ongoing process instance","messagePattern":"Cannot throw process-instance scoped message, since the dispatched event is not part of an ongoing process instance","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/MessageThrowingEventListener.java","lineNumber":44,"sourceCode":"\n/**\n * An {@link FlowableEventListener} that throws a message event when an event is dispatched to it. Sends the message to the execution the event was fired from. If the execution is not subscribed to a\n * message, the process-instance is checked.\n * \n * @author Tijs Rademakers\n * \n */\npublic class MessageThrowingEventListener extends BaseDelegateEventListener {\n\n    protected String messageName;\n    protected Class<?> entityClass;\n\n    @Override\n    public void onEvent(FlowableEvent event) {\n        if (isValidEvent(event) && event instanceof FlowableEngineEvent engineEvent) {\n\n            if (engineEvent.getProcessInstanceId() == null) {\n                throw new FlowableIllegalArgumentException(\"Cannot throw process-instance scoped message, since the dispatched event is not part of an ongoing process instance\");\n            }\n\n            ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();\n            List<MessageEventSubscriptionEntity> subscriptionEntities = processEngineConfiguration.getEventSubscriptionServiceConfiguration()\n                    .getEventSubscriptionService().findMessageEventSubscriptionsByProcessInstanceAndEventName(engineEvent.getProcessInstanceId(), messageName);\n\n            for (EventSubscriptionEntity messageEventSubscriptionEntity : subscriptionEntities) {\n                EventSubscriptionUtil.eventReceived(messageEventSubscriptionEntity, null, false);\n            }\n        }\n    }\n\n    public void setMessageName(String messageName) {\n        this.messageName = messageName;\n    }\n\n    @Override\n    public boolean isFailOnException() {","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/MessageThrowingEventListener.java#L26-L62","documentation":"MessageThrowingEventListener.onEvent throws this FlowableIllegalArgumentException when the event listener is configured to throw a process-instance-scoped message, but the dispatched FlowableEngineEvent has a null processInstanceId. Message subscriptions are looked up per process instance, so an execution/process-instance context is mandatory.","triggerScenarios":"A 'message' event listener with processInstanceScope=true receives an engine event not tied to a running process instance (processInstanceId == null), e.g. an engine-level or job-level event.","commonSituations":"Global event listeners registered in process engine configuration that react to all event types; events fired during deployment or engine startup that carry no process instance; listener attached to a scope event (e.g. FLOWABLE_ENGINE) instead of an activity/job event within a process.","solutions":["Restrict the listener's event types (via event-listener XML 'events' attribute or addEventProcessor filtering) to those always carrying a processInstanceId (activity, task, job execution events).","Check engineEvent.getProcessInstanceId() != null before delegating to the listener in a wrapper listener.","If the signal/message is not meant to be process-scoped, set the listener's scope accordingly so this branch isn't taken.","If triggering messages externally, use runtimeService.messageEventReceived with an explicit subscription instead of the event listener."],"exampleFix":"// before\nlistenerRegistry.addGlobalEventListener(new MessageThrowingEventListener(...)); // receives every event\n\n// after\nif (event instanceof FlowableEngineEvent e && e.getProcessInstanceId() != null) {\n    messageThrowingEventListener.onEvent(event);\n}","handlingStrategy":"type-guard","validationCode":"if (engineEvent.getProcessInstanceId() == null) return; // not process-scoped","typeGuard":"static boolean isProcessScoped(FlowableEvent event) {\n    return event instanceof FlowableEngineEvent && ((FlowableEngineEvent) event).getProcessInstanceId() != null;\n}","tryCatchPattern":"try {\n    listener.onEvent(event);\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"not part of an ongoing process instance\")) {\n        logger.warn(\"skipping process-scoped message for execution-less event {}\", event.getType());\n    }\n}","preventionTips":["Only register process-scoped message listeners for events with a processInstanceId.","Restrict the 'events' attribute in listener XML to concrete activity/job events.","Prefer runtimeService.messageEventReceived for external message delivery."],"tags":["flowable","bpmn","event-listener","message-event","missing-process-instance"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}