flowable/flowable-engine · error · FlowableIllegalArgumentException
Incompatible type set on field declaration '${name}' for cla
Error message
Incompatible type set on field declaration '${name}' for class ${target.getClass().getName()}. Declared value has type ${value.getClass().getName()}, while expecting ${field.getType().getName()} What it means
After locating the target field, invokeSetterOrField checks that the value's type is assignable to the field's declared type via fieldTypeCompatible. If not, it throws this FlowableIllegalArgumentException detailing the value type and the expected field type.
Source
Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/util/ReflectUtil.java:181
public static void invokeSetterOrField(Object target, String name, Object value, boolean throwExceptionOnMissingField) {
Method setterMethod = getSetter(name, target.getClass(), value.getClass());
if (setterMethod != null) {
invokeSetter(setterMethod, target, name, value);
} else {
Field field = ReflectUtil.getField(name, target);
if (field == null) {
if (throwExceptionOnMissingField) {
throw new FlowableIllegalArgumentException("Field definition uses non-existent field '" + name + "' of class " + target.getClass().getName());
} else {
return;
}
}
// Check if the delegate field's type is correct
if (!fieldTypeCompatible(value, field)) {
throw new FlowableIllegalArgumentException("Incompatible type set on field declaration '" + name
+ "' for class " + target.getClass().getName()
+ ". Declared value has type " + value.getClass().getName()
+ ", while expecting " + field.getType().getName());
}
setField(field, target, value);
}
}
/**
* Returns the field of the given object or null if it doesn't exist.
*/
public static Field getField(String fieldName, Object object) {
return getField(fieldName, object.getClass());
}
/**
* Returns the field of the given class or null if it doesn't exist.View on GitHub (pinned to d6d39ce1c6)
Solutions
- Align the field's declared type with the injected value type (e.g. change String field to int, or inject a String value).
- In BPMN XML, set the correct type attribute on <flowable:field>/<flowable:value> (e.g. stringValue, expression).
- For numeric fields, ensure the value resolves to the numeric type, or accept a String and parse it inside the delegate.
- Update the process definition after refactoring field types.
- Check both the value.getClass() and expected type printed in the message to pinpoint the mismatch.
Example fix
// before private int retryLimit; // injected with <flowable:string value="10"/> // after <flowable:field name="retryLimit"><flowable:value>10</flowable:value></flowable:field> <!-- numeric injection --> // or change field to String and parse
Defensive patterns
Strategy: validation
Validate before calling
Field f = target.getClass().getDeclaredField(name);
if (!f.getType().isAssignableFrom(value.getClass())
&& !(f.getType().isPrimitive() && isCompatiblePrimitive(f.getType(), value.getClass())))
throw new IllegalStateException("Value " + value.getClass() + " not assignable to " + f.getType()); Try / catch
try {
ReflectUtil.invokeSetterOrField(target, name, value, true);
} catch (FlowableIllegalArgumentException e) {
LOGGER.error("Field {} type mismatch: {}", name, e.getMessage());
throw new IllegalArgumentException("Fix injected value type for field " + name, e);
} Prevention
- Set explicit type attributes (stringValue, expression) on field injection elements
- Keep field types and BPMN injection types in sync during refactors
- Parse strings inside delegates rather than relying on auto-conversion
- Test field injection with a delegate smoke test at deploy time
When it happens
Trigger: Injecting a value whose runtime type does not match the declared field type — e.g. a String field injection into an int/long field, a String into a custom bean field, or an expression that resolves to a different type than the field expects, in flowable:field definitions.
Common situations: BPMN field injection where the delegate declares int/boolean but the XML value is a string without the right type attribute; expression evaluating to the wrong type; changed field type after refactor.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Could not set field ${field}
- Field definition uses non-existent field '${name}' of class
- Illegal access when calling '<fieldName>' on class <classNam
- Exception while invoking '<fieldName>' on class <className>
- Incompatible type set on field declaration '<fieldName>' for
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/880b263c2c283ed9.
Report an issue: GitHub.