{"record":{"id":"6843b1e200651098","repo":"flowable/flowable-engine","slug":"error-value-set-rvalue-6843b1","errorCode":null,"errorMessage":"error.value.set.rvalue","messagePattern":"error\\.value\\.set\\.rvalue","errorType":"exception","errorClass":"ELException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstProperty.java","lineNumber":144,"sourceCode":"\t\tif (base == null) {\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.property.base.null\", prefix));\n\t\t}\n\t\tObject property = getProperty(bindings, context);\n\t\tif (property == null && strict) {\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.property.property.notfound\", \"null\", base));\n\t\t}\n\t\tcontext.setPropertyResolved(false);\n\t\tboolean result = context.getELResolver().isReadOnly(context, base, property);\n\t\tif (!context.isPropertyResolved()) {\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.property.property.notfound\", property, base));\n\t\t}\n\t\treturn result;\n\t}\n\n\t@Override\n\tpublic void setValue(Bindings bindings, ELContext context, Object value) throws ELException {\n\t\tif (!lvalue) {\n\t\t\tthrow new ELException(LocalMessages.get(\"error.value.set.rvalue\", getStructuralId(bindings)));\n\t\t}\n\t\tObject base = prefix.eval(bindings, context);\n\t\tif (base == null) {\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.property.base.null\", prefix));\n\t\t}\n\t\tObject property = getProperty(bindings, context);\n\t\tif (property == null && strict) {\n\t\t\tthrow new PropertyNotFoundException(LocalMessages.get(\"error.property.property.notfound\", \"null\", base));\n\t\t}\n\t\tcontext.setPropertyResolved(false);\n\t\tClass<?> type = context.getELResolver().getType(context, base, property);\n\t\tif (context.isPropertyResolved()) {\n\t\t\tif (type != null && (value != null || type.isPrimitive())) {\n\t\t\t\tvalue = bindings.convert(value, type);\n\t\t\t}\n\t\t\tcontext.setPropertyResolved(false);\n\t\t}\n\t\tcontext.getELResolver().setValue(context, base, property, value);","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/tree/impl/ast/AstProperty.java#L126-L162","documentation":"ELException with message error.value.set.rvalue: setValue() was called on an expression AST node that is not an lvalue (the node was parsed as a right-hand value only). The library refuses to assign through an expression that has no assignable target, such as a literal, arithmetic result, or method call. This is a programming/config error in which the expression was never intended to be a write target.","triggerScenarios":"Calling setValue() on an AstProperty created with lvalue=false (e.g. parsed from a non-assignment expression) or on rvalue node types; using an expression like ${1+1} or ${bean.compute()} as a set target in a task listener / variable mapping.","commonSituations":"Flowable task listener 'expression' fields configured with computed expressions where an assignment was expected; misuse of the EL API attempting to write into method-call results; copy-paste of a read expression into a write slot of a variable scope configuration.","solutions":["Use a plain lvalue expression (a variable or property path like ${order.status}) as the assignment target","Compute values in code/delegate and set the variable directly instead of assigning through a computed expression","Re-check the flowable configuration field: replace 'expression' with 'delegateExpression' or a value expression as appropriate","Parse the expression and inspect the AST if you need to validate lvalue-ness before calling setValue"],"exampleFix":"// before\nexpression: \"${order.total + surcharge}\"  // used as set target -> rvalue\n// after\nexpression: \"${order.totalWithSurcharge}\" // plain property lvalue; compute elsewhere\n","handlingStrategy":"validation","validationCode":"// reject rvalue expressions before calling setValue\nif (!expressionText.matches(\"\\\\$\\\\{[A-Za-z_$][\\\\w$.]*\\\\}\")) {\n    throw new IllegalArgumentException(\"Not an lvalue expression: \" + expressionText);\n}","typeGuard":"boolean isLvalue(AstNode n) { return n instanceof AstProperty || n instanceof AstIdentifier; }","tryCatchPattern":"try {\n    node.setValue(bindings, context, value);\n} catch (ELException e) {\n    log.error(\"Cannot assign through rvalue expression\", e);\n    throw new IllegalArgumentException(\"Expression must be an assignable path\", e);\n}","preventionTips":["Use only plain variable/property paths as assignment targets","Compute derived values in delegates, not in write-target expressions","Parse-and-inspect the AST before setValue in generic tooling","Review Flowable listener config fields that mix 'expression' and value semantics"],"tags":["el","expression-language","assignment","rvalue"],"backgroundTag":"unsupported-operation","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}