flowable/flowable-engine · error · FlowableIllegalStateException
No TaskListener implementation found for…
Error message
No TaskListener implementation found for implementationType=" + listener.getImplementationType() + " implementation=" + listener.getImplementation()
What it means
createTaskListener instantiates a TaskListener from a FlowableListener based on its implementationType (class, expression, delegateExpression, instance, script). If the type matches none of the known implementation types, it throws FlowableIllegalStateException because no factory path can build a listener.
Solutions
- Correct the implementationType to one of: class, expression, delegateExpression, instance, script
- If using XML, fix the flowable:class / flowable:expression / flowable:delegateExpression attribute so the parser infers the right type
- Check the Flowable version — older XML with non-standard types may need migration
Example fix
// before <flowable:taskListener event="create" implentation="com.example.MyListener" /> // after <flowable:taskListener event="create" class="com.example.MyListener" />
Defensive patterns
Strategy: validation
Validate before calling
Set<String> valid = Set.of("class","expression","delegateExpression","instance","script");
if (!valid.contains(listener.getImplementationType())) throw new IllegalStateException("bad implementationType: " + listener.getImplementationType()); Try / catch
try {
repositoryService.createDeployment().addClasspathResource(p).deploy();
} catch (FlowableIllegalStateException e) {
if (e.getMessage().contains("No TaskListener implementation found")) log.error("Unsupported listener implementationType");
} Prevention
- Only use the five supported implementation types
- Prefer XML attributes (flowable:class/expression/delegateExpression) so the parser sets the type
- Pin listener builder constants from Flowable API instead of hand-written strings
When it happens
Trigger: A task listener is registered with an implementationType other than class/expression/delegateExpression/instance/script (e.g. misspelled type string in XML, or a listener built programmatically with an unsupported/empty implementation type).
Common situations: Typo like implentation="class" or implementationType="javaclass" in BPMN XML; custom tooling writing listener definitions with a wrong type constant; version drift where a new implementation type isn't handled by this engine version.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Cannot create an event-throwing event-listener, unknown…
- Delegate expression " + expression + " did not resolve to…
- Delegate expression did not resolve to an implementation of…
- Exception while invoking TaskListener
- No event defined for taskListener in UserTask '" +…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/541177c913286acd.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/listener/ListenerNotificationHelper.java:162
BaseTaskListener taskListener = null;
ListenerFactory listenerFactory = CommandContextUtil.getProcessEngineConfiguration().getListenerFactory();
if (ImplementationType.IMPLEMENTATION_TYPE_CLASS.equalsIgnoreCase(listener.getImplementationType())) {
taskListener = listenerFactory.createClassDelegateTaskListener(listener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_EXPRESSION.equalsIgnoreCase(listener.getImplementationType())) {
taskListener = listenerFactory.createExpressionTaskListener(listener);
} else if (ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION.equalsIgnoreCase(listener.getImplementationType())) {
if (listener.getOnTransaction() != null) {
taskListener = listenerFactory.createTransactionDependentDelegateExpressionTaskListener(listener);
} else {
taskListener = listenerFactory.createDelegateExpressionTaskListener(listener);
}
} else if (ImplementationType.IMPLEMENTATION_TYPE_INSTANCE.equalsIgnoreCase(listener.getImplementationType())) {
taskListener = (TaskListener) listener.getInstance();
} else if (ImplementationType.IMPLEMENTATION_TYPE_SCRIPT.equalsIgnoreCase(listener.getImplementationType())) {
taskListener = listenerFactory.createScriptTypeTaskListener(listener);
} else {
throw new FlowableIllegalStateException(
"No TaskListener implementation found for implementationType=" + listener.getImplementationType() + " implementation="
+ listener.getImplementation());
}
return taskListener;
}
protected void planTransactionDependentTaskListener(DelegateExecution execution, TransactionDependentTaskListener taskListener, FlowableListener listener) {
Map<String, Object> executionVariablesToUse = execution.getVariables();
CustomPropertiesResolver customPropertiesResolver = createCustomPropertiesResolver(listener);
Map<String, Object> customPropertiesMapToUse = invokeCustomPropertiesResolver(execution, customPropertiesResolver);
TransactionDependentTaskListenerExecutionScope scope = new TransactionDependentTaskListenerExecutionScope(
execution.getProcessInstanceId(), execution.getId(), (Task) execution.getCurrentFlowElement(), executionVariablesToUse, customPropertiesMapToUse);
addTransactionListener(listener, new ExecuteTaskListenerTransactionListener(taskListener, scope,
CommandContextUtil.getProcessEngineConfiguration().getCommandExecutor()));
}
protected CustomPropertiesResolver createCustomPropertiesResolver(FlowableListener listener) {View on GitHub (pinned to d6d39ce1c6)