{"record":{"id":"bdcf73b501cfd57c","repo":"flowable/flowable-engine","slug":"error-while-propagating-error-event","errorCode":null,"errorMessage":"Error while propagating error-event","messagePattern":"Error while propagating error-event","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ErrorThrowingEventListener.java","lineNumber":52,"sourceCode":"        if (isValidEvent(event) && event instanceof FlowableEngineEvent) {\n            FlowableEngineEvent engineEvent = (FlowableEngineEvent) event;\n            ExecutionEntity execution = null;\n\n            if (Context.isExecutionContextActive()) {\n                execution = Context.getExecutionContext().getExecution();\n            } else if (engineEvent.getExecutionId() != null) {\n                // Get the execution based on the event's execution ID instead\n                execution = Context.getCommandContext().getExecutionEntityManager().findExecutionById(engineEvent.getExecutionId());\n            }\n\n            if (execution == null) {\n                throw new ActivitiException(\"No execution context active and event is not related to an execution. No compensation event can be thrown.\");\n            }\n\n            try {\n                ErrorPropagation.propagateError(errorCode, execution);\n            } catch (Exception e) {\n                throw new ActivitiException(\"Error while propagating error-event\", e);\n            }\n        }\n    }\n\n    public void setErrorCode(String errorCode) {\n        this.errorCode = errorCode;\n    }\n\n    @Override\n    public boolean isFailOnException() {\n        return true;\n    }\n}\n","sourceCodeStart":34,"sourceCodeEnd":66,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/ErrorThrowingEventListener.java#L34-L66","documentation":"This ActivitiException wraps any failure that occurs while the event listener propagates a BPMN error event to an execution via ErrorPropagation.propagateError(errorCode, execution). It is thrown from ErrorThrowingEventListener.onEvent when an error-start/boundary-event style listener fires but the propagation itself fails (no matching boundary/error handler, or an internal exception during propagation). The original cause is attached as the wrapped exception.","triggerScenarios":"A Flowable event (e.g. TASK_COMPLETED, ACTIVITY_SIGNALLED, etc.) is dispatched to a registered ErrorThrowingEventListener with an errorCode; ErrorPropagation.propagateError is invoked but throws — e.g. no scope/execution context available, no matching error boundary event or error start event exists for the errorCode, or an exception occurs while searching the execution hierarchy.","commonSituations":"Configuring an error-throwing event listener in the process definition whose errorCode does not match any boundary error event or error start event in the process; firing the listener from a global event (no execution context) so the error cannot be attached to an execution; typos in errorCode values; cascading failures inside an error handler triggered during rollback.","solutions":["Inspect the wrapped cause (getCause()) to see the underlying propagation failure and fix that first.","Verify the listener's errorCode exactly matches the errorRef of a boundary error event or error start event in the process definition.","Ensure the event the listener is bound to is execution-related; do not register the error-throwing listener for events without an execution context.","Check the process definition has an error handler (boundaryEvent with errorEventDefinition) in an enclosing scope for the activity where the event fires.","Log/step through ErrorPropagation.propagateError to see whether any scope matched the error code."],"exampleFix":"// before: listener fires, but no matching error handler\n<extensionElements>\n  <activiti:eventListener events=\"TASK_COMPLETED\" errorCode=\"MY_ERROR\"/>\n</extensionElements>\n\n// after: add a matching boundary error handler with errorRef=\"MY_ERROR\"\n<boundaryEvent id=\"errBoundary\" attachedToRef=\"theTask\">\n  <errorEventDefinition errorRef=\"MY_ERROR\"/>\n</boundaryEvent>","handlingStrategy":"try-catch","validationCode":"// before relying on the listener, confirm a matching error handler exists\nboolean hasHandler = process.getFlowElements().stream()\n    .filter(BoundaryEvent.class::isInstance)\n    .map(BoundaryEvent.class::cast)\n    .flatMap(be -> be.getEventDefinitions().stream())\n    .filter(ErrorEventDefinition.class::isInstance)\n    .map(ed -> ((ErrorEventDefinition) ed).getErrorCode())\n    .anyMatch(code -> code == null || code.equals(\"MY_ERROR\"));\nif (!hasHandler) throw new IllegalStateException(\"No error handler for errorCode MY_ERROR\");","typeGuard":null,"tryCatchPattern":"try {\n    eventDispatcher.dispatchEvent(myEvent);\n} catch (ActivitiException e) {\n    logger.error(\"error-event propagation failed, cause={} \", e.getCause(), e);\n    throw e;\n}","preventionTips":["Always pair an error-throwing event listener errorCode with a boundary/error-start event errorRef.","Register error-throwing listeners only on execution-related events.","Keep errorCode strings as constants shared between listener config and error definitions.","Log the wrapped cause, not just the outer message, when debugging propagation failures."],"tags":["bpmn","error-event","process-engine","listener"],"backgroundTag":"internal-invariant-violation","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"}