{"record":{"id":"918fbf1142e997a4","repo":"flowable/flowable-engine","slug":"delegate-expression-expression-did-neither-res","errorCode":null,"errorMessage":"Delegate expression + expression + did neither resolve to an implementation of + ActivityBehavior.class + nor + JavaDelegate.class","messagePattern":"Delegate expression \\+ expression \\+ did neither resolve to an implementation of \\+ ActivityBehavior\\.class \\+ nor \\+ JavaDelegate\\.class","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ServiceTaskDelegateExpressionActivityBehavior.java","lineNumber":205,"sourceCode":"                } else if (delegate instanceof FutureJavaDelegate) {\n                    FutureJavaDelegate<Object> futureJavaDelegate = (FutureJavaDelegate<Object>) delegate;\n                    DelegateInvocation invocation = new FutureJavaDelegateInvocation(futureJavaDelegate, execution,\n                            processEngineConfiguration.getAsyncTaskInvoker());\n                    processEngineConfiguration.getDelegateInterceptor().handleInvocation(invocation);\n\n                    Object invocationResult = invocation.getInvocationResult();\n                    if (invocationResult instanceof CompletableFuture) {\n                        CompletableFuture<Object> future = (CompletableFuture<Object>) invocationResult;\n\n                        CommandContextUtil.getAgenda(commandContext).planFutureOperation(future, new FutureJavaDelegateCompleteAction(futureJavaDelegate, execution, loggingSessionEnabled));\n                    } else {\n                        throw new FlowableIllegalStateException(\n                                \"Invocation result \" + invocationResult + \" from invocation \" + invocation + \" was not a CompletableFuture\");\n                    }\n\n\n                } else {\n                    throw new FlowableIllegalArgumentException(\"Delegate expression \" + expression + \" did neither resolve to an implementation of \" + ActivityBehavior.class + \" nor \" + JavaDelegate.class);\n                }\n\n            } else {\n                if (loggingSessionEnabled) {\n                    BpmnLoggingSessionUtil.addLoggingData(LoggingSessionConstants.TYPE_SKIP_TASK, \"Skipped service task \" + execution.getCurrentActivityId() +\n                            \" with skip expression \" + skipExpressionText, execution);\n                }\n                leave(execution);\n            }\n        } catch (Exception exc) {\n\n            handleException(exc, execution, loggingSessionEnabled);\n\n        }\n    }\n\n    protected void handleException(Throwable exc, DelegateExecution execution, boolean loggingSessionEnabled) {\n        if (loggingSessionEnabled) {","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/behavior/ServiceTaskDelegateExpressionActivityBehavior.java#L187-L223","documentation":"ServiceTaskDelegateExpressionActivityBehavior.execute throws FlowableIllegalArgumentException when a service task's delegate expression resolves to an object that implements neither ActivityBehavior nor JavaDelegate. The delegate expression must produce one of these two supported types for Flowable to execute the task.","triggerScenarios":"The expression `${someBean}` resolves to a bean in the Spring/CDI container that is not a JavaDelegate or ActivityBehavior — e.g. a plain service class, wrong type registered under the expected name, or a proxy losing the interface.","commonSituations":"Spring bean renamed or replaced with a different type; bean is a plain @Service without implements JavaDelegate; AOP proxies (e.g. @Transactional) hiding the interface from expression resolution; copy-paste of expression referencing the wrong bean.","solutions":["Make the delegate class implement JavaDelegate (or ActivityBehavior) and confirm the execute(DelegateExecution) method is public","Verify the bean referenced by the delegate expression is of the intended type in the application context","Check that AOP proxying does not strip the JavaDelegate interface (add interface-aware proxying or proxyTargetClass)","Test the expression resolution in isolation: expression.getValue returns the bean; assert instanceof JavaDelegate"],"exampleFix":"// before\n@Service(\"orderProcessor\")\npublic class OrderProcessor { public void process(Order o) {...} }\n// after\n@Service(\"orderProcessor\")\npublic class OrderProcessor implements JavaDelegate {\n  public void execute(DelegateExecution execution) {...}\n}","handlingStrategy":"validation","validationCode":"// Verify the bean the delegate expression resolves to implements JavaDelegate\nObject bean = applicationContext.getBean(\"orderProcessor\");\nif (!(bean instanceof JavaDelegate) && !(bean instanceof ActivityBehavior)) {\n    throw new IllegalStateException(\"Delegate bean must implement JavaDelegate or ActivityBehavior\");\n}","typeGuard":"public static boolean isValidDelegate(Object o) {\n    return o instanceof JavaDelegate || o instanceof ActivityBehavior;\n}","tryCatchPattern":"try {\n    processEngine.getRuntimeService().startProcessInstanceByKey(processKey);\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"did neither resolve to an implementation of\")) {\n        // fix bean type or expression reference\n    }\n}","preventionTips":["Make delegate classes explicitly implement JavaDelegate","Use interface-aware AOP proxying so proxies keep JavaDelegate","Keep a startup check that all delegate-expression beans implement the required interface"],"tags":["service-task","delegate-expression","type-mismatch","spring","flowable"],"backgroundTag":"incompatible-source-type","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"}