{"record":{"id":"406775741a56b94c","repo":"flowable/flowable-engine","slug":"error-identifier-method-notfound","errorCode":null,"errorMessage":"error.identifier.method.notfound","messagePattern":"error\\.identifier\\.method\\.notfound","errorType":"exception","errorClass":"MethodNotFoundException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstIdentifier.java","lineNumber":145,"sourceCode":"\n\t@Override\n\tpublic boolean isReadOnly(Bindings bindings, ELContext context) {\n\t\tValueExpression expression = bindings.getVariable(index);\n\t\tif (expression != null) {\n\t\t\treturn expression.isReadOnly(context);\n\t\t}\n\t\tcontext.setPropertyResolved(false);\n\t\tboolean result = context.getELResolver().isReadOnly(context, null, name);\n\t\tif (!context.isPropertyResolved()) {\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.identifier.property.notfound\", name));\n\t\t}\n\t\treturn result;\n\t}\n\n\tprotected MethodExpression getMethodExpression(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes) {\n\t\tObject value = eval(bindings, context);\n\t\tif (value == null) {\n\t\t\tthrow new MethodNotFoundException(LocalMessages.get(\"error.identifier.method.notfound\", name));\n\t\t}\n\t\tif (value instanceof Method) {\n\t\t\tfinal Method method = findAccessibleMethod((Method)value);\n\t\t\tif (method == null) {\n\t\t\t\tthrow new MethodNotFoundException(LocalMessages.get(\"error.identifier.method.notfound\", name));\n\t\t\t}\n\t\t\tif (!ignoreReturnType && returnType != null && !returnType.isAssignableFrom(method.getReturnType())) {\n\t\t\t\tthrow new MethodNotFoundException(LocalMessages.get(\"error.identifier.method.returntype\", method.getReturnType(), name, returnType));\n\t\t\t}\n\t\t\tif (!Arrays.equals(method.getParameterTypes(), paramTypes)) {\n\t\t\t\tthrow new MethodNotFoundException(LocalMessages.get(\"error.identifier.method.notfound\", name));\n\t\t\t}\n\t\t\treturn new MethodExpression() {\n\t\t\t\tprivate static final long serialVersionUID = 1L;\n\t\t\t\t@Override\n\t\t\t\tpublic boolean isLiteralText() {\n\t\t\t\t\treturn false;\n\t\t\t\t}","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstIdentifier.java#L127-L163","documentation":"Thrown from getMethodExpression when evaluating the identifier yields null. A method expression ${myBean.myMethod(...)} requires the identifier to reference an object (or java.lang.reflect.Method), but the resolved value was null, so there is no method to invoke. Reported as MethodNotFoundException naming the identifier.","triggerScenarios":"Calling MethodExpression.invoke() or getMethodInfo() (via AstIdentifier.invoke/getMethodInfo) where the identifier evaluates to null — e.g. variable not set or bean property is null.","commonSituations":"Task listener/execution listener delegation expression pointing at a bean that is null; Spring bean not yet injected or missing from application context; process variable holding the delegate cleared before the listener fires.","solutions":["Ensure the referenced bean/variable is non-null when the expression evaluates (check Spring bean registration, @Component scan)","Set the process variable before the listener/condition runs","Fix the identifier spelling","Add a resolver (e.g. Spring bean resolver) so the name maps to the actual bean"],"exampleFix":"// before: variable 'delegateBean' never set, expression ${delegateBean.execute(execution)}\n// after: provide the bean\nexecution.setVariable(\"delegateBean\", applicationContext.getBean(MyDelegate.class));","handlingStrategy":"type-guard","validationCode":"Object bean = applicationContext.getBeanProvider(DelegateType.class).getIfAvailable();\nif (bean == null) throw new IllegalStateException(\"delegateBean not registered in Spring context\");","typeGuard":"boolean methodTargetPresent(String varName, VariableScope scope) {\n  return scope.getVariable(varName) != null;\n}","tryCatchPattern":"try {\n  methodExpr.invoke(context, params);\n} catch (MethodNotFoundException e) {\n  logger.error(\"Method target '{}' is null; check bean/variable wiring\", e.getMessage());\n  throw new FlowableException(\"Missing method expression target\", e);\n}","preventionTips":["Verify Spring beans referenced in delegation expressions exist at startup (actuator/health check)","Never clear the variable that holds the delegate before listeners complete","Use fully qualified bean names in expressions and test them in unit tests","Prefer class-based delegation (flowable:class=...) over bean-based when wiring is uncertain"],"tags":["el","method-expression","null-value","flowable"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}