{"record":{"id":"6ac4f8890a165757","repo":"flowable/flowable-engine","slug":"couldn-t-execute-event-listener","errorCode":null,"errorMessage":"couldn't execute event listener : ","messagePattern":"couldn't execute event listener : ","errorType":"exception","errorClass":"PvmException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AbstractEventAtomicOperation.java","lineNumber":47,"sourceCode":"        return false;\n    }\n\n    @Override\n    public void execute(InterpretableExecution execution) {\n        ScopeImpl scope = getScope(execution);\n        List<ExecutionListener> executionListeners = scope.getExecutionListeners(getEventName());\n        int executionListenerIndex = execution.getExecutionListenerIndex();\n\n        if (executionListeners.size() > executionListenerIndex) {\n            execution.setEventName(getEventName());\n            execution.setEventSource(scope);\n            ExecutionListener listener = executionListeners.get(executionListenerIndex);\n            try {\n                listener.notify(execution);\n            } catch (RuntimeException e) {\n                throw e;\n            } catch (Exception e) {\n                throw new PvmException(\"couldn't execute event listener : \" + e.getMessage(), e);\n            }\n            execution.setExecutionListenerIndex(executionListenerIndex + 1);\n            execution.performOperation(this);\n\n        } else {\n            execution.setExecutionListenerIndex(0);\n            execution.setEventName(null);\n            execution.setEventSource(null);\n\n            eventNotificationsCompleted(execution);\n        }\n    }\n\n    protected abstract ScopeImpl getScope(InterpretableExecution execution);\n\n    protected abstract String getEventName();\n\n    protected abstract void eventNotificationsCompleted(InterpretableExecution execution);","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AbstractEventAtomicOperation.java#L29-L65","documentation":"PvmException wrapping an unexpected checked Exception thrown by an ExecutionListener's notify() during an atomic operation. RuntimeExceptions are rethrown unchanged; only checked (non-runtime) exceptions from listener code get wrapped. The message concatenates the cause's message, so the root reason comes from the listener implementation.","triggerScenarios":"An ExecutionListener attached to an activity/transition/process-scope event throws a checked Exception during execution of the event atomic operation.","commonSituations":"Listener code doing I/O (file, network, reflection) that declares checked exceptions, e.g. a listener reading a script file or calling a legacy API.","solutions":["Fix or wrap the exception inside the listener: catch checked exceptions in notify() and either handle them or rethrow as a RuntimeException.","Inspect the wrapped cause (e.getCause()) / message to find the actual listener failure.","Ensure listeners only throw RuntimeExceptions, per the ActivitiExecutionListener contract."],"exampleFix":"// before\npublic void notify(DelegateExecution e) throws IOException {\n  Files.write(path, data); // checked exception escapes\n}\n// after\npublic void notify(DelegateExecution e) {\n  try {\n    Files.write(path, data);\n  } catch (IOException ioe) {\n    throw new RuntimeException(\"listener failed writing output\", ioe);\n  }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  processEngine.getRuntimeService().signal(executionId, vars);\n} catch (PvmException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"couldn't execute event listener\")) {\n    Throwable cause = e.getCause(); // the listener's original checked exception\n    log.error(\"Execution listener failed: \" + cause.getMessage(), cause);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Never let checked exceptions escape ExecutionListener.notify(); wrap them in RuntimeException.","Keep listeners side-effect-light and defensive (null/IO checks inside the listener).","Test every registered listener before deploying the process definition."],"tags":["java","pvm","execution-listener","wrapped-exception"],"backgroundTag":"listener-threw-exception","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}