flowable/flowable-engine · error · MethodNotFoundException
error.identifier.method.notfound
Error message
error.identifier.method.notfound
What it means
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.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstIdentifier.java:145
@Override
public boolean isReadOnly(Bindings bindings, ELContext context) {
ValueExpression expression = bindings.getVariable(index);
if (expression != null) {
return expression.isReadOnly(context);
}
context.setPropertyResolved(false);
boolean result = context.getELResolver().isReadOnly(context, null, name);
if (!context.isPropertyResolved()) {
throw new PropertyNotFoundException(LocalMessages.get("error.identifier.property.notfound", name));
}
return result;
}
protected MethodExpression getMethodExpression(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes) {
Object value = eval(bindings, context);
if (value == null) {
throw new MethodNotFoundException(LocalMessages.get("error.identifier.method.notfound", name));
}
if (value instanceof Method) {
final Method method = findAccessibleMethod((Method)value);
if (method == null) {
throw new MethodNotFoundException(LocalMessages.get("error.identifier.method.notfound", name));
}
if (!ignoreReturnType && returnType != null && !returnType.isAssignableFrom(method.getReturnType())) {
throw new MethodNotFoundException(LocalMessages.get("error.identifier.method.returntype", method.getReturnType(), name, returnType));
}
if (!Arrays.equals(method.getParameterTypes(), paramTypes)) {
throw new MethodNotFoundException(LocalMessages.get("error.identifier.method.notfound", name));
}
return new MethodExpression() {
private static final long serialVersionUID = 1L;
@Override
public boolean isLiteralText() {
return false;
}View on GitHub (pinned to d6d39ce1c6)
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
Example fix
// before: variable 'delegateBean' never set, expression ${delegateBean.execute(execution)}
// after: provide the bean
execution.setVariable("delegateBean", applicationContext.getBean(MyDelegate.class)); Defensive patterns
Strategy: type-guard
Validate before calling
Object bean = applicationContext.getBeanProvider(DelegateType.class).getIfAvailable();
if (bean == null) throw new IllegalStateException("delegateBean not registered in Spring context"); Type guard
boolean methodTargetPresent(String varName, VariableScope scope) {
return scope.getVariable(varName) != null;
} Try / catch
try {
methodExpr.invoke(context, params);
} catch (MethodNotFoundException e) {
logger.error("Method target '{}' is null; check bean/variable wiring", e.getMessage());
throw new FlowableException("Missing method expression target", e);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- error.method.literal.void
- error.method.invalid
- error.method.notypes
- error.identifier.method.returntype
- Script content is null or evaluated to null for taskListener
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/406775741a56b94c.
Report an issue: GitHub.