{"record":{"id":"df3ede9885840765","repo":"flowable/flowable-engine","slug":"field-definition-uses-non-existing-field-fieldna","errorCode":null,"errorMessage":"Field definition uses non-existing field '<fieldName>' on class <className>","messagePattern":"Field definition uses non-existing field '<fieldName>' on class <className>","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/ClassDelegateUtil.java","lineNumber":64,"sourceCode":"    }\n\n    public static void applyFieldDeclaration(FieldDeclaration declaration, Object target) {\n        Method setterMethod = ReflectUtil.getSetter(declaration.getName(), target.getClass(), declaration.getValue().getClass());\n\n        if (setterMethod != null) {\n            try {\n                setterMethod.invoke(target, declaration.getValue());\n            } catch (IllegalArgumentException e) {\n                throw new FlowableException(\"Error while invoking '\" + declaration.getName() + \"' on class \" + target.getClass().getName(), e);\n            } catch (IllegalAccessException e) {\n                throw new FlowableException(\"Illegal access when calling '\" + declaration.getName() + \"' on class \" + target.getClass().getName(), e);\n            } catch (InvocationTargetException e) {\n                throw new FlowableException(\"Exception while invoking '\" + declaration.getName() + \"' on class \" + target.getClass().getName(), e);\n            }\n        } else {\n            Field field = ReflectUtil.getField(declaration.getName(), target);\n            if (field == null) {\n                throw new FlowableIllegalArgumentException(\"Field definition uses non-existing field '\" + declaration.getName() + \"' on class \" + target.getClass().getName());\n            }\n            // Check if the delegate field's type is correct\n            if (!fieldTypeCompatible(declaration, field)) {\n                throw new FlowableIllegalArgumentException(\"Incompatible type set on field declaration '\" + declaration.getName() + \"' for class \" + target.getClass().getName() + \". Declared value has type \"\n                        + declaration.getValue().getClass().getName() + \", while expecting \" + field.getType().getName());\n            }\n            ReflectUtil.setField(field, target, declaration.getValue());\n        }\n    }\n\n    public static boolean fieldTypeCompatible(FieldDeclaration declaration, Field field) {\n        if (declaration.getValue() != null) {\n            return field.getType().isAssignableFrom(declaration.getValue().getClass());\n        } else {\n            // Null can be set any field type\n            return true;\n        }\n    }","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/bpmn/helper/ClassDelegateUtil.java#L46-L82","documentation":"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.","triggerScenarios":"<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.","commonSituations":"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.","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"],"exampleFix":"// before\n<flowable:field name=\"timeOut\" stringValue=\"10\"/>\n// after (delegate has field 'timeout')\n<flowable:field name=\"timeout\" stringValue=\"10\"/>","handlingStrategy":"validation","validationCode":"// Validate BPMN field names against delegate fields before deployment\nSet<String> available = ReflectUtil.getFields(delegateClass).keySet();\nif (!available.contains(declaredFieldName)) {\n    throw new DeploymentException(\"Field \" + declaredFieldName + \" missing on \" + delegateClass.getName());\n}","typeGuard":"static boolean delegateHasField(Class<?> delegate, String name) {\n    try { delegate.getDeclaredField(name); return true; }\n    catch (NoSuchFieldException e) { return false; }\n}","tryCatchPattern":"try { deploy(processDefinition); }\ncatch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"non-existing field\")) {\n        log.error(\"BPMN references missing delegate field: {}\", e.getMessage());\n    } else throw e;\n}","preventionTips":["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"],"tags":["java","field-injection","bpmn","config-typo"],"backgroundTag":"resource-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}