flowable/flowable-engine · error · ELException
Error '${property}' on type '${base.getClass().getName()}'
Error message
Error '${property}' on type '${base.getClass().getName()}' What it means
BeanELResolver.setValue wraps exceptions thrown by a bean's setter invoked during EL assignment in an ELException with the message "Error '<property>' on type '<class>'". The real failure inside the setter is preserved as the cause via InvocationTargetException.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/javax/el/BeanELResolver.java:190
throw new PropertyNotWritableException("resolver is read-only");
}
BeanProperty beanProperty = property(base, property);
if (beanProperty == null) {
return;
}
Method method = beanProperty.write(base);
if (method == null) {
throw new PropertyNotWritableException("Cannot write property: '" + property + "' on type " + base.getClass().getName());
}
context.setPropertyResolved(base, property);
try {
invoke(method, base, value);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
Util.handleThrowable(cause);
throw new ELException("Error '" + property + "' on type '" + base.getClass().getName() + "'", cause);
} catch (Exception e) {
throw new ELException(e);
}
}
@Override
public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) {
Objects.requireNonNull(context, "context is null");
if (base == null || method == null) {
return null;
}
Object result = null;
if (params == null) {
params = new Object[0];
}
String name = method.toString();
Method target = Util.findMethod(context, base.getClass(), base, name, paramTypes, params);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Inspect the ELException's cause — fix the logic inside the setter.
- Ensure the assigned EL value's type matches the setter parameter type.
- Validate/sanitize the value before the assignment expression runs.
Example fix
// before
public void setAge(String a) { this.age = Integer.parseInt(a); } // throws on 'abc'
// after
public void setAge(Integer a) { this.age = a; } // EL passes matching type Defensive patterns
Strategy: try-catch
Validate before calling
// pre-validate value type against setter
Class<?> pt = new PropertyDescriptor(prop, bean.getClass()).getWriteMethod().getParameterTypes()[0]; if (!pt.isInstance(value)) throw new IllegalArgumentException("type mismatch"); Try / catch
try { resolver.setValue(ctx, base, prop, val); } catch (ELException e) { log.error("setter failed for " + prop, e.getCause()); } Prevention
- Match EL-assigned values to setter parameter types
- Keep setters free of throwing validation; validate upstream
- Log the cause chain, not just the ELException
When it happens
Trigger: Evaluating ${bean.name = value} where calling the matching setXxx(value) method throws — e.g. IllegalArgumentException from type conversion inside the setter, NPE, or validation failure in the setter body.
Common situations: Setters with validation or type coercion logic rejecting the EL-supplied value (e.g. assigning a String to an int property via a lenient path); setters performing persistence that fails.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- Error reading '' on type ''
- ELException
- Cannot write property: '${property}' on type ${base.getClass
- Cannot find method ${name} with ${params.length} parameters
- resolver is read-only
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/304c0a3a48fa42b3.
Report an issue: GitHub.