{"record":{"id":"bfd16249c0763e01","repo":"flowable/flowable-engine","slug":"delegateclassname-doesn-t-implement-flowablecoll-bfd162","errorCode":null,"errorMessage":"<delegateClassName> doesn't implement FlowableCollectionHandler","messagePattern":"<delegateClassName> doesn't implement FlowableCollectionHandler","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/DelegateExpressionCollectionHandler.java","lineNumber":48,"sourceCode":"\tprotected Expression expression;\n\n    public DelegateExpressionCollectionHandler(DelegateExecution execution, Expression expression) {\n        this.execution = execution;\n        this.expression = expression;\n    }\n\n\t@Override\n\t@SuppressWarnings(\"rawtypes\")\n\tpublic Collection resolveCollection(Object collectionValue, DelegateExecution execution) {\n\t\treturn getCollectionHandlerInstance(execution).resolveCollection(collectionValue, execution);\n\t}\n\n    protected FlowableCollectionHandler getCollectionHandlerInstance(DelegateExecution execution) {\n        Object delegateInstance = DelegateExpressionUtil.resolveDelegateExpression(expression, execution);\n        if (delegateInstance instanceof FlowableCollectionHandler) {\n            return (FlowableCollectionHandler) delegateInstance;\n        } else {\n            throw new FlowableIllegalArgumentException(delegateInstance.getClass().getName() + \" doesn't implement \" + FlowableCollectionHandler.class);\n        }\n    }\n}\n","sourceCodeStart":30,"sourceCodeEnd":52,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/DelegateExpressionCollectionHandler.java#L30-L52","documentation":"Thrown by DelegateExpressionCollectionHandler.getCollectionHandlerInstance as a FlowableIllegalArgumentException when a delegate expression configured for a multi-instance/collection handler resolves to an object that does not implement FlowableCollectionHandler. Flowable cannot use the resolved bean as a collection handler, so it fails fast.","triggerScenarios":"A collection handler delegate expression (e.g. ${myBean}) resolves a Spring/CDI bean whose class does not implement org.flowable.engine.impl...FlowableCollectionHandler, during resolveCollection.","commonSituations":"Wiring an arbitrary bean or a JavaDelegate where a FlowableCollectionHandler is expected; renamed/moved interface after a Flowable version upgrade; bean returning a proxy/wrapper of the wrong type; copy-pasted delegate expression from another task.","solutions":["Make the referenced bean implement FlowableCollectionHandler (provide getCollection(DelegateExecution))","Point the delegate expression at a bean that actually implements FlowableCollectionHandler","Verify the resolved object's runtime type (watch for proxies that mask the interface)","Check the correct Flowable module/API is on the classpath so the interface matches"],"exampleFix":"// before\npublic class MyBean { public List<String> getItems() { ... } }\n// after\npublic class MyBean implements FlowableCollectionHandler {\n    public List<String> getCollection(DelegateExecution execution) { ... }\n}","handlingStrategy":"type-guard","validationCode":"Object bean = applicationContext.getBean(beanName);\nif (!(bean instanceof FlowableCollectionHandler)) {\n    throw new IllegalStateException(beanName + \" must implement FlowableCollectionHandler\");\n}","typeGuard":"static boolean isCollectionHandler(Expression expr, DelegateExecution exec) {\n    Object d = DelegateExpressionUtil.resolveDelegateExpression(expr, exec);\n    return d instanceof FlowableCollectionHandler;\n}","tryCatchPattern":"try { startProcess(key); }\ncatch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().endsWith(\"doesn't implement \" + FlowableCollectionHandler.class.getName())) {\n        log.error(\"Bad collection handler delegate: {}\", e.getMessage());\n    } else throw e;\n}","preventionTips":["Make all collection-handler beans implement FlowableCollectionHandler explicitly","Assert bean types at application startup","Avoid AOP proxies that hide the implemented interface where possible"],"tags":["java","multi-instance","delegate-expression","wrong-type"],"backgroundTag":"invalid-argument-value","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"}