flowable/flowable-engine · error · ELException
error.value.set.rvalue
Error message
error.value.set.rvalue
What it means
AstRightValue represents non-assignable (rvalue) expression nodes in the embedded JUEL/odysseus EL parser. Its setValue is always final and always throws ELException because an rvalue can never be an assignment target. Flowable throws it when a script or expression tries to write a value into something that is not a variable.
Solutions
- Write to an actual variable instead: use delegateTask.setVariable / runtimeService.setVariable, or a left-value expression like a bare variable or property path.
- If the target is a bean property, expose a setter and use the property path '${myBean.text}' as the lvalue rather than a method call or computed expression.
- Verify the parsed expression root: check isLeftValue() on the node or use AST introspection before calling setValue.
Example fix
// before
expression.setValue(bindings, context, "newValue"); // ${order.total} -> ELException
// after
runtimeService.setVariable(execution.getId(), "orderTotal", "newValue"); Defensive patterns
Strategy: type-guard
Validate before calling
if (valueExpression.isReadOnly(context)) { throw new IllegalArgumentException("Expression is not assignable: " + valueExpression.getExpressionString()); } Type guard
boolean isAssignable(ValueExpression ve, ELContext ctx) { return ve != null && !ve.isReadOnly(ctx); } Try / catch
try { ve.setValue(ctx, value); } catch (ELException e) { log.error("Cannot assign to rvalue expression {}: {}", ve.getExpressionString(), e.getMessage()); } Prevention
- Only call setValue on bare variable or property-path expressions
- Prefer engine setVariable APIs over EL assignment
- Check isReadOnly() before assignment
When it happens
Trigger: Calling ELContext/ExpressionNode setValue (or a ValueExpression.setValue) whose AST root is a right-value node, e.g. setting into a method result, literal, or operator expression like '${a + b}' or '${myBean.getText()}' inside an expression assignment (e.g. flowable:expression used as write target, or delegating expression code calling setValue on the ValueExpression).
Common situations: BPMN process models where an expression is used on the left side of an assignment; misreading `${...}` expressions as settable properties; trying to mutate read-only bean properties via expression in a task listener or service task field injection.
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
- Cannot set value of '', it's readonly!
- error.value.set.rvalue
- error.method.invalid
- error.value.set.rvalue
- Error while evaluating expression
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2f7b055c98d5a035.
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/AstRightValue.java:58
@Override
public final Class<?> getType(Bindings bindings, ELContext context) {
return null;
}
/**
* non-lvalues are always readonly, so answer <code>true</code>
*/
@Override
public final boolean isReadOnly(Bindings bindings, ELContext context) {
return true;
}
/**
* non-lvalues are always readonly, so throw an exception
*/
@Override
public final void setValue(Bindings bindings, ELContext context, Object value) {
throw new ELException(LocalMessages.get("error.value.set.rvalue", getStructuralId(bindings)));
}
@Override
public final MethodInfo getMethodInfo(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes) {
return null;
}
@Override
public final Object invoke(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes, Object[] paramValues) {
throw new ELException(LocalMessages.get("error.method.invalid", getStructuralId(bindings)));
}
@Override
public final boolean isLeftValue() {
return false;
}
@OverrideView on GitHub (pinned to d6d39ce1c6)