flowable/flowable-engine · error · PvmException

couldn't execute event listener :

Error message

couldn't execute event listener : 

What it means

Thrown when an ExecutionListener.notify(execution) registered on a transition 'take' event throws a checked Exception. The PVM rethrows it as a PvmException preserving the cause. Runtime exceptions from listeners are propagated unchanged; only non-Runtime exceptions are wrapped.

Solutions

  1. Inspect the cause of the PvmException to find the listener's checked exception
  2. Fix or catch the checked exception inside the listener's notify() method
  3. Wrap checked exceptions in a RuntimeException (e.g. ActivitiException) within the listener
  4. Verify the listener class is on the classpath and its notify() handles failure conditions

Example fix

// before
public void notify(DelegateExecution exec) throws Exception {
  Files.write(path, bytes); // throws IOException
}
// after
public void notify(DelegateExecution exec) {
  try { Files.write(path, bytes); }
  catch (IOException e) { throw new ActivitiException("listener write failed", e); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure listener class resolves before deployment
Class.forName(listenerClassName);

Try / catch

try {
  taskService.complete(taskId);
} catch (PvmException e) {
  log.error("execution listener failed on take", e.getCause());
}

Prevention

When it happens

Trigger: An ExecutionListener configured on a sequence flow's take event implements notify() with checked exceptions (e.g. I/O, reflection, custom checked types) that are not caught inside the listener.

Common situations: Listeners doing JMS/HTTP notifications or file access; custom listeners written for older Java where checked exceptions were declared; misconfigured listener classes failing to load/invoke via reflection.

Related errors


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/AtomicOperationTransitionNotifyListenerTake.java:57

    }

    @Override
    public void execute(InterpretableExecution execution) {
        TransitionImpl transition = execution.getTransition();

        List<ExecutionListener> executionListeners = transition.getExecutionListeners();
        int executionListenerIndex = execution.getExecutionListenerIndex();

        if (executionListeners.size() > executionListenerIndex) {
            execution.setEventName(org.activiti.engine.impl.pvm.PvmEvent.EVENTNAME_TAKE);
            execution.setEventSource(transition);
            ExecutionListener listener = executionListeners.get(executionListenerIndex);
            try {
                listener.notify(execution);
            } catch (RuntimeException e) {
                throw e;
            } catch (Exception e) {
                throw new PvmException("couldn't execute event listener : " + e.getMessage(), e);
            }
            execution.setExecutionListenerIndex(executionListenerIndex + 1);
            execution.performOperation(this);

        } else {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("{} takes transition {}", execution, transition);
            }
            execution.setExecutionListenerIndex(0);
            execution.setEventName(null);
            execution.setEventSource(null);

            ActivityImpl activity = (ActivityImpl) execution.getActivity();
            ActivityImpl nextScope = findNextScope(activity.getParent(), transition.getDestination());
            execution.setActivity(nextScope);

            // Firing event that transition is being taken
            if (Context.getProcessEngineConfiguration() != null && Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {

View on GitHub (pinned to d6d39ce1c6)