flowable/flowable-engine · error · ELException
error.property.method.invocation
Error message
error.property.method.invocation
What it means
ELException (error.property.method.invocation) thrown when Method.invoke raises IllegalArgumentException — the actual argument values supplied to the expression do not match the method's declared parameter types. It carries the original exception as cause.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstProperty.java:217
@Override
public Object invoke(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes, Object[] paramValues) {
Object base = prefix.eval(bindings, context);
if (base == null) {
throw new PropertyNotFoundException(LocalMessages.get("error.property.base.null", prefix));
}
Object property = getProperty(bindings, context);
if (property == null && strict) {
throw new PropertyNotFoundException(LocalMessages.get("error.property.method.notfound", "null", base));
}
String name = bindings.convert(property, String.class);
Method method = findMethod(name, base.getClass(), returnType, paramTypes);
try {
return method.invoke(base, paramValues);
} catch (IllegalAccessException e) {
throw new ELException(LocalMessages.get("error.property.method.access", name, base.getClass()), e);
} catch (IllegalArgumentException e) {
throw new ELException(LocalMessages.get("error.property.method.invocation", name, base.getClass()), e);
} catch (InvocationTargetException e) {
throw new ELException(LocalMessages.get("error.property.method.invocation", name, base.getClass()), e.getCause());
}
}
@Override
public AstNode getChild(int i) {
return i == 0 ? prefix : null;
}
}
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Match argument types to the method signature, adding explicit conversions in the expression if needed.
- Change the method to accept the types actually passed (e.g. Object, Number, or a wrapper).
- Convert values before evaluation (set variables of the correct type in the ELContext).
- Ensure the argument count matches the declared parameters, including varargs handling.
Example fix
// before
${calc.add("1", 2)} // add(int, int) — String literal fails
// after
${calc.add(1, 2)} Defensive patterns
Strategy: validation
Validate before calling
java.lang.reflect.Method m = base.getClass().getMethod("add", int.class, int.class);
for (Object arg : args) {
if (arg instanceof String && m.getParameterTypes()[0] == int.class) {
throw new IllegalArgumentException("pass numeric literals in EL, not strings");
}
} Type guard
boolean argsMatch(java.lang.reflect.Method m, Object... args) {
Class<?>[] pts = m.getParameterTypes();
if (args.length != pts.length) return false;
for (int i = 0; i < pts.length; i++) {
if (args[i] != null && !pts[i].isInstance(args[i])
&& !isCoercible(args[i], pts[i])) return false;
}
return true;
} Try / catch
try {
result = expr.invoke(ctx);
} catch (jakarta.el.ELException e) {
if (e.getCause() instanceof IllegalArgumentException) {
log.warn("EL argument type mismatch: {}", e.getMessage());
throw new IllegalStateException("fix argument types in expression", e);
}
throw e;
} Prevention
- Use unquoted numeric literals for numeric parameters in EL
- Add tests exercising each EL expression with realistic argument types
- Coerce types in the backing bean (accept Number/Object) to be lenient
- Keep EL expressions in sync with signature changes via integration tests
When it happens
Trigger: invoke() on ${obj.method(a, b)} where an argument's runtime type is incompatible with the method signature (e.g. passing a String where an int/Long is expected, or wrong number of arguments).
Common situations: EL coercion not converting types as expected (string literals vs numbers); changed method signatures after expression deployment; passing null to primitive parameters; type erasure surprises with collections.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- error.property.method.notfound
- error.property.method.returntype
- error.property.method.access
- <exception message from evaluation failure>
- TypeConverter ${clazz} could not be instantiated
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2ab9d5b04eeafad9.
Report an issue: GitHub.