flowable/flowable-engine · error · ActivitiException

Cannot set value of ' ', it's readonly!

Error message

Cannot set value of '${property}', it's readonly!

What it means

ReadOnlyMapELResolver exposes a wrapped Map to EL as read-only. Its setValue throws ActivitiException whenever the EL expression attempts to write a property that exists in the wrapped map, enforcing that the map cannot be modified from expressions.

Solutions

  1. Remove the assignment from the expression; read-only maps are for reads only
  2. Write through runtimeService.setVariable / execution.setVariable instead of EL assignment
  3. If mutation is intended, pass a mutable map or a real VariableScope rather than the read-only resolver

Example fix

// before (EL)
${myVar = 'newValue'}
// after (Java)
runtimeService.setVariable(executionId, "myVar", "newValue");
Defensive patterns

Strategy: validation

Validate before calling

// Validate the EL does not assign to read-only map keys before evaluation
if (expression != null && expression.matches(".*\\$\\{[^}]*=[^}]*\\}.*")) {
    throw new IllegalArgumentException("Assignments in EL are not allowed on read-only maps");
}

Try / catch

try {
    expressionManager.createExpression(expr).getValue(scope);
} catch (ActivitiException e) {
    if (e.getMessage() != null && e.getMessage().contains("it's readonly")) {
        // write via runtimeService.setVariable instead
    }
}

Prevention

When it happens

Trigger: An EL expression performing an assignment (e.g. ${myMap.key = 'value'} or c:set-style writes) on a base object that is the read-only map with a matching key.

Common situations: Scripts/delegates trying to mutate engine-provided read-only maps (e.g. process variables snapshots, variables maps passed read-only into expressions); accidentally confusing a read-only view with a variable scope.

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


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/el/ReadOnlyMapELResolver.java:56

        if (base == null) {
            if (wrappedMap.containsKey(property)) {
                context.setPropertyResolved(true);
                return wrappedMap.get(property);
            }
        }
        return null;
    }

    @Override
    public boolean isReadOnly(ELContext context, Object base, Object property) {
        return true;
    }

    @Override
    public void setValue(ELContext context, Object base, Object property, Object value) {
        if (base == null) {
            if (wrappedMap.containsKey(property)) {
                throw new ActivitiException("Cannot set value of '" + property + "', it's readonly!");
            }
        }
    }

    @Override
    public Class<?> getCommonPropertyType(ELContext context, Object arg) {
        return Object.class;
    }

    @Override
    public Class<?> getType(ELContext context, Object arg1, Object arg2) {
        return Object.class;
    }
}

View on GitHub (pinned to d6d39ce1c6)