flowable/flowable-engine · error · ELException
error.method.invalid
error.method.invalid
Error message
error.method.invalid
What it means
TreeMethodExpression requires that a non-literal expression which is not a method invocation must at least be a left value (an assignable l-value). If the expression is neither a method invocation nor a left value, construction fails with 'error.method.invalid'.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/TreeMethodExpression.java:92
super();
Tree tree = store.get(expr);
this.builder = store.getBuilder();
this.bindings = tree.bind(functions, variables, converter);
this.expr = expr;
this.type = returnType;
this.types = paramTypes;
this.node = tree.getRoot();
this.deferred = tree.isDeferred();
if (node.isLiteralText()) {
if (returnType == void.class || returnType == Void.class) {
throw new ELException(LocalMessages.get("error.method.literal.void", expr));
}
} else if (!node.isMethodInvocation()) {
if (!node.isLeftValue()) {
throw new ELException(LocalMessages.get("error.method.invalid", expr));
}
if (paramTypes == null) {
throw new NullPointerException(LocalMessages.get("error.method.notypes")); // EL specification requires NPE
}
}
}
private String getStructuralId() {
if (structure == null) {
structure = node.getStructuralId(bindings);
}
return structure;
}
/**
* Evaluates the expression and answers information about the method
* @param context used to resolve properties (<code>base.property</code> and <code>base[property]</code>)
* @return method information or <code>null</code> for literal expressionsView on GitHub (pinned to d6d39ce1c6)
Solutions
- Correct the expression to a valid method invocation, e.g. '#{bean.method(...)}'.
- If you meant a value binding, use TreeValueExpression instead of TreeMethodExpression.
- Verify the parsed expression resolves to an l-value (property access) if intended as an l-value method target.
Example fix
// before
new TreeMethodExpression(store, ctx, fns, vars, "#{bean.prop + 1}", null, Object.class)
// after
new TreeMethodExpression(store, ctx, fns, vars, "#{bean.compute()}", null, Object.class) Defensive patterns
Strategy: validation
Validate before calling
// parse-check: expression must be a method invocation or an l-value
if (!expr.matches("#\{[^}]+\}") && !expr.matches("\$\{[^}]+\}")) {
// literal is ok, else it must resolve to a method or l-value at construction
} Type guard
boolean isValidMethodExpression(String expr) {
return expr.startsWith("#{") && expr.contains("("); // method invocation form
} Try / catch
try {
TreeMethodExpression m = new TreeMethodExpression(store, ctx, fns, vars, expr, paramTypes, returnType);
} catch (ELException e) {
// expression is neither a method invocation nor an l-value; fix the expression
} Prevention
- Use method-invocation syntax (#{bean.method(...)}) for method expressions.
- Use TreeValueExpression for value bindings instead of TreeMethodExpression.
- Check expressions for typos like missing parentheses or non-assignable operands.
When it happens
Trigger: new TreeMethodExpression(...) with an expression like '#{a.b.c}' that resolves to something that is neither a method call nor an assignable property (e.g. an arithmetic result or a nested non-lvalue path).
Common situations: Typo in an expression (missing method name or parentheses); passing a value expression string where a method expression is required; version upgrades tightening validation.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- error.method.literal.void
- error.method.notypes
- error.identifier.method.notfound
- error.identifier.method.returntype
- Variable id cannot be empty
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/124a44f76f6e0061.
Report an issue: GitHub.