{"record":{"id":"739ccf80cc0338a7","repo":"flowable/flowable-engine","slug":"delegate-expression-expression-did-not-resolve-739ccf","errorCode":null,"errorMessage":"Delegate expression + expression + did not resolve to an implementation of FlowableEventListener","messagePattern":"Delegate expression \\+ expression \\+ did not resolve to an implementation of FlowableEventListener","errorType":"exception","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/DelegateExpressionFlowableEventListener.java","lineNumber":56,"sourceCode":"\n    @Override\n    public void onEvent(FlowableEvent event) {\n        if (isValidEvent(event)) {\n            Object delegate = DelegateExpressionUtil.resolveDelegateExpression(expression, new NoExecutionVariableScope());\n            if (delegate instanceof FlowableEventListener) {\n                // Cache result of isFailOnException() from delegate-instance\n                // until next event is received. This prevents us from having to resolve\n                // the expression twice when an error occurs.\n                failOnException = ((FlowableEventListener) delegate).isFailOnException();\n\n                // Call the delegate\n                ((FlowableEventListener) delegate).onEvent(event);\n            } else {\n\n                // Force failing, since the exception we're about to throw\n                // cannot be ignored, because it did not originate from the listener itself\n                failOnException = true;\n                throw new FlowableIllegalArgumentException(\"Delegate expression \" + expression + \" did not resolve to an implementation of \" + FlowableEventListener.class.getName());\n            }\n        }\n    }\n\n    @Override\n    public boolean isFailOnException() {\n        return failOnException;\n    }\n\n}\n","sourceCodeStart":38,"sourceCodeEnd":67,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/DelegateExpressionFlowableEventListener.java#L38-L67","documentation":"Thrown by DelegateExpressionFlowableEventListener.onEvent as a FlowableIllegalArgumentException when the configured delegate expression resolves to an object that is not a FlowableEventListener. Because the failure does not originate from a listener itself, failOnException is forced to true so the error cannot be swallowed.","triggerScenarios":"An event listener registered via delegate expression ${someBean} resolves to a non-listener object at dispatch time; onEvent then throws instead of delegating ((FlowableEventListener) delegate).onEvent(event).","commonSituations":"Bean defined with the wrong type in Spring config; expression typo resolving to a different bean; the bean is conditionally of another type (profiles/environments); refactoring a listener class to drop the interface while listener registrations remain.","solutions":["Make the bean referenced by the expression implement FlowableEventListener","Fix the expression string so it resolves to the intended listener bean","Re-register the listener if it was removed; verify runtime bean type at startup","If the resolved instance should be optional, guard the configuration rather than registering a non-listener"],"exampleFix":"// before\npublic class AuditBean { public void audit(FlowableEvent e) { ... } }\n// after\npublic class AuditBean implements FlowableEventListener {\n    public void onEvent(FlowableEvent event) { audit(event); }\n    public boolean isFailOnException() { return true; }\n}","handlingStrategy":"type-guard","validationCode":"Object resolved = beanFactory.getBean(expressionString);\nif (!(resolved instanceof FlowableEventListener)) {\n    throw new IllegalStateException(\"Listener bean must implement FlowableEventListener: \" + expressionString);\n}","typeGuard":"static boolean isListenerBean(BeanFactory f, String expr) {\n    try { return f.getBean(expr) instanceof FlowableEventListener; } catch (Exception e) { return false; }\n}","tryCatchPattern":"try { runtimeService.startProcessInstanceByKey(key); }\ncatch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"did not resolve to an implementation of \" + FlowableEventListener.class.getName())) {\n        log.error(\"Listener delegate expression wrong type: {}\", e.getMessage());\n    } else throw e;\n}","preventionTips":["Register only FlowableEventListener implementations via delegate expressions","Add a startup check that resolves every registered listener expression once","Verify class-level interface after refactoring listener classes"],"tags":["java","event-listener","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"}