flowable/flowable-engine · error · PropertyNotFoundException
error.property.method.notfound
Error message
error.property.method.notfound
What it means
After resolving the base object, AstMethod.eval asks the property node for the method name; if the property itself is null it throws PropertyNotFoundException('error.property.method.notfound' with name 'null'). This indicates the method-name part of the method expression evaluated to null rather than a String.
Solutions
- Ensure the variable/expression providing the method name is non-null and a non-empty String before evaluation.
- Default the name: ${obj[name != null ? name : 'defaultMethod']()} — or fix the map key/config value.
- Validate inputs feeding the dynamic method name (empty check) upstream.
- Switch to an explicit static method call if dynamic dispatch is not truly needed.
Example fix
// before
${bean[fnName]()} // fnName is null
// after
${bean[fnName != null ? fnName : 'defaultFn']()} Defensive patterns
Strategy: validation
Validate before calling
String methodName = (String) factory.createValueExpression(ctx, "${fnName}", String.class).getValue(context);
if (methodName == null || methodName.isEmpty()) {
throw new IllegalStateException("Dynamic method name must be a non-empty String");
} Type guard
boolean validDynamicMethodName(String s) { return s != null && !s.trim().isEmpty(); } Try / catch
try {
return expr.getValue(context);
} catch (PropertyNotFoundException e) {
if (!e.getMessage().contains("method.notfound")) throw e;
return fallbackMethod();
} Prevention
- Validate variables feeding dynamic method selection before evaluation
- Provide defaults for dynamic method-name variables
- Prefer static method calls when dispatch target is known at authoring time
When it happens
Trigger: Dynamic method access like ${obj[methodName]()} or bracket-style method selection where the inner expression returns null (unset variable, missing map key, resolver returning null).
Common situations: Dynamic dispatch from a configuration variable that was never set; map lookup for the method name returning null because the key is absent; expression built programmatically with a null method token.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- resolver must not be null
- Cannot coerce property to array index:
- Cannot find method with parameters in
- Cannot invoke method
- Cannot parse array index:
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0fe173e82d9f2be8.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstMethod.java:93
}
@Override
public void appendStructure(StringBuilder builder, Bindings bindings) {
property.appendStructure(builder, bindings);
params.appendStructure(builder, bindings);
}
protected Object eval(Bindings bindings, ELContext context, boolean answerNullIfBaseIsNull) {
Object base = property.getPrefix().eval(bindings, context);
if (base == null) {
if (answerNullIfBaseIsNull) {
return null;
}
throw new PropertyNotFoundException(LocalMessages.get("error.property.base.null", property.getPrefix()));
}
Object method = property.getProperty(bindings, context);
if (method == null) {
throw new PropertyNotFoundException(LocalMessages.get("error.property.method.notfound", "null", base));
}
String name = bindings.convert(method, String.class);
context.setPropertyResolved(false);
Object result = context.getELResolver().invoke(context, base, name, null, params.eval(bindings, context));
if (!context.isPropertyResolved()) {
throw new MethodNotFoundException(LocalMessages.get("error.property.method.notfound", name, base.getClass()));
}
return result;
}
@Override
public Object eval(Bindings bindings, ELContext context) {
return eval(bindings, context, true);
}
@Override
public Object invoke(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes, Object[] paramValues) {View on GitHub (pinned to d6d39ce1c6)