flowable/flowable-engine · error · ActivitiIllegalArgumentException
Delegate expression did not resolve to an implementation of…
Error message
Delegate expression ${expression} did not resolve to an implementation of org.flowable.engine.delegate.event.FlowableEventListener What it means
DelegateExpressionActivitiEventListener resolves its delegate from an expression (e.g. a Spring bean). If the resolved object is null or not an instance of FlowableEventListener, it throws ActivitiIllegalArgumentException and forces failure of event dispatch.
Solutions
- Ensure the referenced bean implements org.flowable.engine.delegate.event.FlowableEventListener
- Verify the expression (e.g. ${myListener}) names the correct bean in the application context
- Check the bean is a plain listener implementation, not a proxy/wrapper hiding the interface
- Fix the delegateExpression value in the listener registration config or BPMN XML
Example fix
// before
<flowable:eventListener events="JOB_EXECUTION_SUCCESS" delegateExpression="${myPojo}"/>
// after
<flowable:eventListener events="JOB_EXECUTION_SUCCESS" delegateExpression="${myEventListener}"/> <!-- implements FlowableEventListener --> Defensive patterns
Strategy: validation
Validate before calling
Object bean = applicationContext.getBean("myEventListener");
if (!(bean instanceof FlowableEventListener)) throw new IllegalArgumentException("bean must implement FlowableEventListener"); Prevention
- Verify bean types in a Spring context smoke test before deploying
- Keep listener expressions pointing at dedicated listener beans
- Avoid proxies around listeners unless they expose FlowableEventListener
When it happens
Trigger: A listener registered with a delegateExpression whose expression resolves to a bean that is not a FlowableEventListener (or does not resolve at all to the right type).
Common situations: Spring bean of the wrong type wired into the process engine config; bean defined but wrong interface implemented; expression typo resolving to an unrelated bean; bean scope/proxy returning an unexpected wrapper.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Class does not implement
- No execution context active and event is not related to an…
- doesn't implement
- doesn't implement
- Error while evaluating expression:
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/c52110a43307dbd0.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/bpmn/helper/DelegateExpressionActivitiEventListener.java:56
@Override
public void onEvent(FlowableEvent event) {
if (isValidEvent(event)) {
Object delegate = DelegateExpressionUtil.resolveDelegateExpression(expression, new NoExecutionVariableScope());
if (delegate instanceof FlowableEventListener) {
// Cache result of isFailOnException() from delegate-instance until next
// event is received. This prevents us from having to resolve the expression twice when
// an error occurs.
failOnException = ((FlowableEventListener) delegate).isFailOnException();
// Call the delegate
((FlowableEventListener) delegate).onEvent(event);
} else {
// Force failing, since the exception we're about to throw cannot be ignored, because it
// did not originate from the listener itself
failOnException = true;
throw new ActivitiIllegalArgumentException("Delegate expression " + expression
+ " did not resolve to an implementation of " + FlowableEventListener.class.getName());
}
}
}
@Override
public boolean isFailOnException() {
return failOnException;
}
}
View on GitHub (pinned to d6d39ce1c6)