flowable/flowable-engine · error · ELException

error.value.set.rvalue

Error message

error.value.set.rvalue

What it means

AstMethod represents a method invocation in an EL expression, which is a transient value. Its setValue always throws ELException('error.value.set.rvalue', i.e. 'Cannot set value of an rvalue'), because you cannot assign to the result of a method call.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstMethod.java:54

	@Override
	public boolean isLiteralText() {
		return false;
	}

	@Override
	public Class<?> getType(Bindings bindings, ELContext context) {
		return null;
	}

	@Override
	public boolean isReadOnly(Bindings bindings, ELContext context) {
		return true;
	}

	@Override
	public void setValue(Bindings bindings, ELContext context, Object value) {
		throw new ELException(LocalMessages.get("error.value.set.rvalue", getStructuralId(bindings)));
	}

	@Override
	public MethodInfo getMethodInfo(Bindings bindings, ELContext context, Class<?> returnType, Class<?>[] paramTypes) {
		return null;
	}

	@Override
	public boolean isLeftValue() {
		return false;
	}
	
	@Override
	public boolean isMethodInvocation() {
		return true;
	}
	
	@Override

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Replace the method-call target with a settable property expression: ${bean.name} instead of ${bean.getName()}.
  2. Invoke a setter method via method invocation semantics instead of setValue, e.g. evaluate ${bean.setName(value)}.
  3. Check isReadOnly()/isLiteralText on the ValueExpression before calling setValue.

Example fix

// before
ve.setValue(context, "x"); // ve = ${obj.getName()}
// after
// use a property expression
ValueExpression ve2 = factory.createValueExpression(ctx, "${obj.name}", String.class);
ve2.setValue(context, "x");
Defensive patterns

Strategy: validation

Validate before calling

if (valueExpression.isLiteralText() || isMethodExpression(valueExpression.getExpressionString())) {
    throw new UnsupportedOperationException("Cannot set value of rvalue: " + valueExpression.getExpressionString());
}
// isMethodExpression: expression ends with ')' or contains '('

Type guard

boolean isWritablePropertyExpr(String expr) {
    String e = expr.trim();
    return e.startsWith("${") && !e.contains("(") && !e.endsWith(")");
}

Try / catch

try {
    ve.setValue(context, value);
} catch (ELException e) {
    if (!e.getMessage().contains("error.value.set.rvalue") && !e.getMessage().contains("rvalue")) throw e;
    // convert to a setter invocation or property assignment
}

Prevention

When it happens

Trigger: Calling ValueExpression.setValue on an expression that is a method call, e.g. setValue on ${bean.getName()}; generic framework code attempting to write through a parsed expression that is a method invocation rather than a property path.

Common situations: Binding frameworks that blindly call setValue on expressions; typos where a setter call should have been a property assignment ${bean.name = x}; EL expressions used as writable bindings when they are read-only.

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/ab7725815d10035e. Report an issue: GitHub.