flowable/flowable-engine · error · NullPointerException
Cannot invoke method
Error message
Cannot invoke method
What it means
RootPropertyResolver.invoke resolves the (base, method) pair and, if it matches the root, throws NullPointerException 'Cannot invoke method <m> on null' because the resolver holds no invocable object for the method. It signals that method dispatch is unsupported on this root resolver.
Solutions
- Expose the method on the actual root object or switch to a BeanNameResolver/ELResolver that supports method invocation.
- Replace the method call with a precomputed property: set the result via setProperty and reference the property in the expression.
- Verify the method name against the root object's public methods before evaluating.
Example fix
// before
resolver.invoke(ctx, root, "formatDate", null, null); // NPE
// after
resolver.setProperty("formattedDate", formatter.format(date));
el.eval("${formattedDate}"); Defensive patterns
Strategy: validation
Validate before calling
Method m = root.getClass().getMethod(methodName); if (m == null) throw new IllegalArgumentException("Method not invocable on root: " + methodName); Try / catch
try { resolver.invoke(ctx, root, method, null, null); } catch (NullPointerException | ELException e) { log.error("Cannot invoke {} on root resolver", method); } Prevention
- Only call methods exposed on real bean resolvers, not the root property resolver
- Precompute method results into properties before evaluation
- Keep root object method names in sync with expressions via tests
When it happens
Trigger: Evaluating an EL method call like '${root.someMethod()}' where base is the root object managed by RootPropertyResolver and no such method exists/is invocable on the root.
Common situations: Expressions calling helper methods that were never exposed on the root object; expecting the root resolver to behave like a bean resolver; renamed methods after refactoring.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- resolver must not be null
- Cannot find property
- error.method.invalid
- error.property.method.notfound
- Resolver is read only!
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/aa52737ee0ede427.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/util/RootPropertyResolver.java:105
public boolean isReadOnly(ELContext context, Object base, Object property) {
return resolve(context, base, property) ? readOnly : false;
}
@Override
public void setValue(ELContext context, Object base, Object property, Object value)
throws PropertyNotWritableException {
if (resolve(context, base, property)) {
if (readOnly) {
throw new PropertyNotWritableException("Resolver is read only!");
}
setProperty((String) property, value);
}
}
@Override
public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) {
if (resolve(context, base, method)) {
throw new NullPointerException("Cannot invoke method " + method + " on null");
}
return null;
}
/**
* Get property value
*
* @param property
* property name
* @return value associated with the given property
*/
public Object getProperty(String property) {
return map.get(property);
}
/**
* Set property value
* View on GitHub (pinned to d6d39ce1c6)