flowable/flowable-engine · error · FlowableIllegalArgumentException
Field definition uses non-existing field '<fieldName>' on cl
Error message
Field definition uses non-existing field '<fieldName>' on class <className>
What it means
Thrown by ClassDelegateUtil.applyFieldDeclaration as a FlowableIllegalArgumentException when the field declaration's name does not match any field on the target delegate class (ReflectUtil.getField returns null). It means the BPMN field injection references a property that does not exist on the delegate.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/ClassDelegateUtil.java:64
}
public static void applyFieldDeclaration(FieldDeclaration declaration, Object target) {
Method setterMethod = ReflectUtil.getSetter(declaration.getName(), target.getClass(), declaration.getValue().getClass());
if (setterMethod != null) {
try {
setterMethod.invoke(target, declaration.getValue());
} catch (IllegalArgumentException e) {
throw new FlowableException("Error while invoking '" + declaration.getName() + "' on class " + target.getClass().getName(), e);
} catch (IllegalAccessException e) {
throw new FlowableException("Illegal access when calling '" + declaration.getName() + "' on class " + target.getClass().getName(), e);
} catch (InvocationTargetException e) {
throw new FlowableException("Exception while invoking '" + declaration.getName() + "' on class " + target.getClass().getName(), e);
}
} else {
Field field = ReflectUtil.getField(declaration.getName(), target);
if (field == null) {
throw new FlowableIllegalArgumentException("Field definition uses non-existing field '" + declaration.getName() + "' on class " + target.getClass().getName());
}
// Check if the delegate field's type is correct
if (!fieldTypeCompatible(declaration, field)) {
throw new FlowableIllegalArgumentException("Incompatible type set on field declaration '" + declaration.getName() + "' for class " + target.getClass().getName() + ". Declared value has type "
+ declaration.getValue().getClass().getName() + ", while expecting " + field.getType().getName());
}
ReflectUtil.setField(field, target, declaration.getValue());
}
}
public static boolean fieldTypeCompatible(FieldDeclaration declaration, Field field) {
if (declaration.getValue() != null) {
return field.getType().isAssignableFrom(declaration.getValue().getClass());
} else {
// Null can be set any field type
return true;
}
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Correct the field name in the BPMN XML to match an existing field or setter on the delegate class
- Add the missing field (with public setter) to the delegate class
- Verify the class/delegateExpression on the service task points at the intended class
- Search the process definitions for all <flowable:field> names and validate against delegate sources at build time
Example fix
// before <flowable:field name="timeOut" stringValue="10"/> // after (delegate has field 'timeout') <flowable:field name="timeout" stringValue="10"/>
Defensive patterns
Strategy: validation
Validate before calling
// Validate BPMN field names against delegate fields before deployment
Set<String> available = ReflectUtil.getFields(delegateClass).keySet();
if (!available.contains(declaredFieldName)) {
throw new DeploymentException("Field " + declaredFieldName + " missing on " + delegateClass.getName());
} Type guard
static boolean delegateHasField(Class<?> delegate, String name) {
try { delegate.getDeclaredField(name); return true; }
catch (NoSuchFieldException e) { return false; }
} Try / catch
try { deploy(processDefinition); }
catch (FlowableIllegalArgumentException e) {
if (e.getMessage().contains("non-existing field")) {
log.error("BPMN references missing delegate field: {}", e.getMessage());
} else throw e;
} Prevention
- Keep field names in BPMN XML and delegate classes in sync; rename together
- Run process-definition validation as part of CI
- Avoid hand-edited XML; use Flowable Modeler which validates field names
When it happens
Trigger: <flowable:field name="..."> in the process definition names a field/setter that is absent on the class instantiated for the service task, so applyFieldDeclaration fails after the setter lookup falls through to ReflectUtil.getField.
Common situations: Typo in the field name in BPMN XML; refactored/renamed delegate field without updating the process definition; wrong delegateExpression/class pointing at a class without that field; copying process XML between projects.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Incompatible type set on field declaration '<fieldName>' for
- Illegal access when calling '%s' on class %s
- Exception while invoking '%s' on class %s
- Field definition uses unexisting field '%s' on class %s
- Incompatible type set on field declaration '%s' for class %s
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/df3ede9885840765.
Report an issue: GitHub.