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

  1. Inspect the ELException's cause — fix the logic inside the setter.
  2. Ensure the assigned EL value's type matches the setter parameter type.
  3. 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

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


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