flowable/flowable-engine · error · MethodNotFoundException

error.identifier.method.notamethod

Error message

error.identifier.method.notamethod

What it means

AstIdentifier.getMethodExpression resolves an identifier to a method to invoke. If the bound value is neither a Java method/FunctionMapper result nor a MethodExpression, it throws MethodNotFoundException naming the identifier and the actual value class. It means the EL expression calls something like ${name(args)} but 'name' resolved to an ordinary object that is not callable.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstIdentifier.java:196

					try {
						return method.invoke(null, params);
					} catch (IllegalAccessException e) {
						throw new ELException(LocalMessages.get("error.identifier.method.access", name), e);
					} catch (IllegalArgumentException e) {
						throw new ELException(LocalMessages.get("error.identifier.method.invocation", name, e));
					} catch (InvocationTargetException e) {
						throw new ELException(LocalMessages.get("error.identifier.method.invocation", name, e.getCause()));
					}
				}			
				@Override
				public MethodInfo getMethodInfo(ELContext context) {
					return new MethodInfo(method.getName(), method.getReturnType(), method.getParameterTypes());
				}
			};
		} else if (value instanceof MethodExpression) {
			return (MethodExpression)value;
		}
		throw new MethodNotFoundException(LocalMessages.get("error.identifier.method.notamethod", name, value.getClass()));
	}

	@Override
	public MethodInfo getMethodInfo(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes) {
		return getMethodExpression(bindings, context, returnType, paramTypes).getMethodInfo(context);
	}

	@Override
	public Object invoke(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes, Object[] params) {
		return getMethodExpression(bindings, context, returnType, paramTypes).invoke(context, params);
	}

	@Override
	public String toString() {
		return name;
	}

	@Override 

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Fix the expression: use property access ${obj.field} instead of invoking it as a method, or call the method on the object ${obj.method(x)}.
  2. Ensure the identifier is actually bound to a method (register it via the ELContext FunctionMapper or bind a LambdaExpression) instead of a plain value.
  3. Correct the identifier spelling / variable name so it resolves to the intended callable.
  4. Inspect the class name in the message to see what the identifier actually resolved to and adjust bindings accordingly.

Example fix

// before
${toUpperCase(name)}   // toUpperCase not a registered function
// after
${name.toUpperCase()}  // method call on the value
Defensive patterns

Strategy: validation

Validate before calling

Object v = factory.createValueExpression(ctx, "${name}", Object.class).getValue(context);
if (!(v instanceof java.lang.reflect.Method || v instanceof MethodExpression || v instanceof LambdaExpression)) {
    throw new IllegalStateException("Identifier 'name' is not callable: " + v);
}

Type guard

boolean isCallable(Object v) {
    return v instanceof java.lang.reflect.Method
        || v instanceof MethodExpression
        || v instanceof LambdaExpression;
}

Prevention

When it happens

Trigger: Invoking an identifier as a method in EL (e.g. ${myHelper(x)}) when the bound identifier evaluates to a plain value (String, bean, null-wrapped object) rather than a method reference or MethodExpression; bindings missing a method entry because the FunctionMapper/ELResolver did not provide one.

Common situations: Typo in a function name registered via EL functions; calling a bean property as a method (writing ${obj.field()} instead of ${obj.field}); a variable bound in a process/delegation was expected to be a lambda/method but is a plain serialized value; upgrading Flowable/EL versions where method resolution via resolver was removed.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/dc47b73d280b0434. Report an issue: GitHub.