flowable/flowable-engine · error · PropertyNotWritableException
Resolver is read only!
Error message
Resolver is read only!
What it means
RootPropertyResolver can be constructed in read-only mode; any attempt to write a property through it then throws PropertyNotWritableException('Resolver is read only!'). This protects root context objects (e.g. process variables views) from mutation via EL.
Solutions
- Construct the RootPropertyResolver with readOnly=false (new RootPropertyResolver(map, false)) if writes are intended.
- Write values through the engine API (setVariable) instead of EL assignment.
- Check resolver.isReadOnly() / ValueExpression.isReadOnly() before attempting setValue.
Example fix
// before RootPropertyResolver resolver = new RootPropertyResolver(map); // readOnly default true resolver.setValue(ctx, root, "count", 3); // throws // after RootPropertyResolver resolver = new RootPropertyResolver(map, false);
Defensive patterns
Strategy: validation
Validate before calling
if (resolver.isReadOnly()) { throw new IllegalStateException("Root resolver is read-only; use engine APIs to persist values"); } Try / catch
try { resolver.setValue(ctx, base, prop, value); } catch (PropertyNotWritableException e) { log.error("Resolver is read-only: {}", e.getMessage()); } Prevention
- Construct with readOnly=false only when writes are required
- Persist state via runtimeService/delegate setVariable instead of EL writes
- Document read-only resolvers for script authors
When it happens
Trigger: Calling ELResolver.setValue / ValueExpression.setValue where the resolved base is a root object handled by a read-only RootPropertyResolver (created with readOnly=true).
Common situations: Assigning to root properties in expressions evaluated with a read-only resolver; scripts that try to persist values by writing back to the root context instead of using engine APIs.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Cannot find property
- Cannot invoke method
- Cannot set value of '', it's readonly!
- error.value.set.rvalue
- error.value.set.rvalue
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/163447405cfcb1a4.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/de/odysseus/el/util/RootPropertyResolver.java:96
if (!isProperty((String) property)) {
throw new PropertyNotFoundException("Cannot find property " + property);
}
return getProperty((String) property);
}
return null;
}
@Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
return resolve(context, base, property) ? readOnly : false;
}
@Override
public void setValue(ELContext context, Object base, Object property, Object value)
throws PropertyNotWritableException {
if (resolve(context, base, property)) {
if (readOnly) {
throw new PropertyNotWritableException("Resolver is read only!");
}
setProperty((String) property, value);
}
}
@Override
public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) {
if (resolve(context, base, method)) {
throw new NullPointerException("Cannot invoke method " + method + " on null");
}
return null;
}
/**
* Get property value
*
* @param property
* property nameView on GitHub (pinned to d6d39ce1c6)