flowable/flowable-engine · error · FlowableIllegalArgumentException
<delegateClassName> doesn't implement FlowableCollectionHand
Error message
<delegateClassName> doesn't implement FlowableCollectionHandler
What it means
ClassDelegateCollectionHandler instantiates the class configured as a collection handler for multi-instance activities and casts it to FlowableCollectionHandler. If the instance does not implement that interface, a FlowableIllegalArgumentException naming the class and the expected interface is thrown. The engine needs this interface to resolve the collection of items a multi-instance activity iterates over.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/ClassDelegateCollectionHandler.java:54
super(className, fieldDeclarations);
}
public ClassDelegateCollectionHandler(Class<?> clazz, List<FieldDeclaration> fieldDeclarations) {
super(clazz, fieldDeclarations);
}
@Override
@SuppressWarnings("rawtypes")
public Collection resolveCollection(Object collectionValue, DelegateExecution execution) {
return getCollectionHandlerInstance().resolveCollection(collectionValue, execution);
}
protected FlowableCollectionHandler getCollectionHandlerInstance() {
Object delegateInstance = instantiateDelegate(className, fieldDeclarations);
if (delegateInstance instanceof FlowableCollectionHandler) {
return (FlowableCollectionHandler) delegateInstance;
} else {
throw new FlowableIllegalArgumentException(delegateInstance.getClass().getName() + " doesn't implement " + FlowableCollectionHandler.class);
}
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Make the configured class implement org.flowable.engine.delegate.FlowableCollectionHandler (getCollection(DelegateExecution)).
- Verify the XML attribute points to the intended fully qualified handler class.
- If the collection is static or expression-based, use flowable:collection with an expression instead of a handler class.
- Redeploy the process application with the corrected handler.
Example fix
// before
public class MyCollection { public List<String> items() { ... } }
// after
public class MyCollection implements FlowableCollectionHandler {
@Override public Collection<String> getCollection(DelegateExecution execution) { ... }
} Defensive patterns
Strategy: validation
Validate before calling
Class<?> c = Class.forName(handlerClass);
if (!FlowableCollectionHandler.class.isAssignableFrom(c))
throw new IllegalStateException("Collection handler must implement FlowableCollectionHandler"); Type guard
boolean isValidHandler(Object o) { return o instanceof FlowableCollectionHandler; } Try / catch
try {
runtimeService.startProcessInstanceByKey("proc");
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().contains("FlowableCollectionHandler")) { /* fix handler class */ }
throw e;
} Prevention
- Implement FlowableCollectionHandler for handler-class based multi-instance collections.
- Prefer expression collections when a simple list suffices.
- Validate handler classes at deployment time.
When it happens
Trigger: A multi-instance activity declares a collection handler class (flowable:collectionHandler / delegateExpression style config) whose class does not implement org.flowable.engine.delegate.FlowableCollectionHandler; resolveCollection triggers the check.
Common situations: Using an ordinary List-returning bean class instead of a FlowableCollectionHandler implementation; wrong class name in the BPMN XML; refactoring removed the interface; stale deployment jar.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- <delegateClassName> doesn't implement TransactionDependentEx
- <delegateClassName> doesn't implement CustomPropertiesResolv
- <delegateClassName> doesn't implement TaskListener
- <delegateClassName> doesn't implement TransactionDependentTa
- <delegateClassName> doesn't implement JavaDelegate, FutureJa
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/7d8d5968caa85ff1.
Report an issue: GitHub.