flowable/flowable-engine · error · ActivitiException
Unknown method used in expression
Error message
Unknown method used in expression: ${expressionText} What it means
JuelExpression.getValue also catches MethodNotFoundException from the EL resolver, thrown when an expression invokes a method that doesn't exist on the resolved target (e.g. ${myBean.calculateX(1)} where calculateX is absent or has an incompatible signature). The engine wraps it in this ActivitiException with the expression text.
Solutions
- Check that the method exists on the target bean with the exact name and is public.
- Match the EL argument count and types; add overloads or convert arguments (e.g. ${bean.calc('${num}' == null ? 0 : num)}).
- Update BPMN expressions after refactoring method names.
- Remember JUEL has no varargs/autoboxing nuance — declare simpler signatures or do conversion inside the method.
Example fix
// before: BPMN calls ${orderService.getTotl(order)} but method renamed
public BigDecimal getTotal(Order o) {...}
// after: update the expression to ${orderService.getTotal(order)} Defensive patterns
Strategy: validation
Validate before calling
// Reflection pre-check that the method exists before the task runs:
Object bean = applicationContext.getBean("orderService");
for (java.lang.reflect.Method m : bean.getClass().getMethods()) {
if (m.getName().equals("getTotal") && m.getParameterCount() == 1) return;
}
throw new IllegalStateException("orderService.getTotal not found — expression will fail"); Try / catch
try {
Object v = juelExpression.getValue(container);
} catch (ActivitiException e) {
if (e.getCause() instanceof MethodNotFoundException) {
throw new IllegalStateException("BPMN expression references missing method: " + e.getMessage());
} else { throw e; }
} Prevention
- Rename methods atomically together with BPMN XML updates (search expressions in *.bpmn files).
- Keep EL-invoked bean methods public with simple, unambiguous signatures.
- Write integration tests that execute every service task expression.
When it happens
Trigger: Evaluating a method-call expression ${bean.method(...)} during getValue where the method name or its parameter types do not match any method on the target object (including JUEL's limited type-coercion rules).
Common situations: Renaming a method on a delegate/bean without updating BPMN expressions, wrong number or types of arguments (EL coercion, e.g. passing a String where an int is expected), method not public, or bean of a different type than expected.
Related errors
- Cannot set value of '', it's readonly!
- error.method.invalid
- error.value.set.rvalue
- error.value.set.rvalue
- Error while evaluating expression
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/57c103585afea57d.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/el/JuelExpression.java:57
public JuelExpression(ValueExpression valueExpression, String expressionText) {
this.valueExpression = valueExpression;
this.expressionText = expressionText;
}
@Override
public Object getValue(VariableContainer variableContainer) {
ELContext elContext = Context.getProcessEngineConfiguration().getExpressionManager().getElContext((VariableScope) variableContainer);
try {
ExpressionGetInvocation invocation = new ExpressionGetInvocation(valueExpression, elContext);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(invocation);
return invocation.getInvocationResult();
} catch (PropertyNotFoundException pnfe) {
throw new ActivitiException("Unknown property used in expression: " + expressionText, pnfe);
} catch (MethodNotFoundException mnfe) {
throw new ActivitiException("Unknown method used in expression: " + expressionText, mnfe);
} catch (ELException ele) {
throw new ActivitiException("Error while evaluating expression: " + expressionText, ele);
} catch (Exception e) {
throw new ActivitiException("Error while evaluating expression: " + expressionText, e);
}
}
@Override
public void setValue(Object value, VariableContainer variableContainer) {
ELContext elContext = Context.getProcessEngineConfiguration().getExpressionManager().getElContext((VariableScope) variableContainer);
try {
ExpressionSetInvocation invocation = new ExpressionSetInvocation(valueExpression, elContext, value);
Context.getProcessEngineConfiguration()
.getDelegateInterceptor()
.handleInvocation(invocation);
} catch (Exception e) {
throw new ActivitiException("Error while evaluating expression: " + expressionText, e);
}View on GitHub (pinned to d6d39ce1c6)