{"record":{"id":"e7c3b9532115ae1c","repo":"flowable/flowable-engine","slug":"field-definition-uses-non-existent-field-name","errorCode":null,"errorMessage":"Field definition uses non-existent field '${name}' of class ${target.getClass().getName()}","messagePattern":"Field definition uses non-existent field '(.+?)' of class (.+?)","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/util/ReflectUtil.java","lineNumber":173,"sourceCode":"            Method method = findMethod(clazz, methodName, args);\n            method.setAccessible(true);\n            return method.invoke(target, args);\n        } catch (Exception e) {\n            throw new FlowableException(\"couldn't invoke \" + methodName + \" on \" + target, e);\n        }\n    }\n    \n    public static void invokeSetterOrField(Object target, String name, Object value, boolean throwExceptionOnMissingField) {\n        Method setterMethod = getSetter(name, target.getClass(), value.getClass());\n\n        if (setterMethod != null) {\n            invokeSetter(setterMethod, target, name, value);\n            \n        } else {\n            Field field = ReflectUtil.getField(name, target);\n            if (field == null) {\n                if (throwExceptionOnMissingField) {\n                    throw new FlowableIllegalArgumentException(\"Field definition uses non-existent field '\" + name + \"' of class \" + target.getClass().getName());\n                } else {\n                    return;\n                }\n            }\n\n            // Check if the delegate field's type is correct\n            if (!fieldTypeCompatible(value, field)) {\n                throw new FlowableIllegalArgumentException(\"Incompatible type set on field declaration '\" + name\n                        + \"' for class \" + target.getClass().getName()\n                        + \". Declared value has type \" + value.getClass().getName()\n                        + \", while expecting \" + field.getType().getName());\n            }\n            \n            setField(field, target, value);\n        }\n    }\n\n    /**","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/util/ReflectUtil.java#L155-L191","documentation":"ReflectUtil.invokeSetterOrField injects a value into a target object via a setter or direct field. When no setter exists, the matching field cannot be found on the target class, and throwExceptionOnMissingField is true, it throws this FlowableIllegalArgumentException naming the missing field and class.","triggerScenarios":"Calling invokeSetterOrField(target, name, value, true) where the target class (and superclasses) define neither a setter nor a field with that name; in Flowable, class-level field injection in process definitions (flowable:field) referencing a property that doesn't exist on the delegate class.","commonSituations":"Typo in field name in BPMN XML <flowable:field name=\"...\">; delegate class refactored/renamed a field after the process definition was authored; injecting a field into a class that expects constructor/setter injection instead.","solutions":["Verify the field name spelling matches a field declared on the target class (or superclass).","Add the field or a setter with the configured name to the delegate class.","Update the process definition / configuration to use the renamed field.","If the field is genuinely optional, call with throwExceptionOnMissingField=false (when using the API directly).","Deploy the updated delegate class together with the corrected process definition."],"exampleFix":"// before\n<flowable:field name=\"recipiants\"> <!-- typo -->\n// after\n<flowable:field name=\"recipients\"> <!-- matches delegate field -->","handlingStrategy":"validation","validationCode":"boolean exists = false;\ntry { target.getClass().getDeclaredField(name); exists = true; }\ncatch (NoSuchFieldException ignored) { }\nif (!exists && java.util.Arrays.stream(target.getClass().getMethods()).noneMatch(m -> m.getName().equalsIgnoreCase(\"set\" + name)))\n    throw new IllegalStateException(\"No field/setter \" + name + \" on \" + target.getClass().getName());","typeGuard":null,"tryCatchPattern":"try {\n    ReflectUtil.invokeSetterOrField(target, name, value, true);\n} catch (FlowableIllegalArgumentException e) {\n    LOGGER.error(\"Field injection misconfigured: {}\", e.getMessage());\n    throw new DeploymentConfigurationException(e.getMessage(), e);\n}","preventionTips":["Verify every flowable:field name exists on the delegate class before deploying","Search BPMN files for field names after renaming fields in code","Use constants or codegen for field names shared between XML and Java","Deploy delegate classes and process definitions atomically"],"tags":["reflection","field-injection","config","java"],"backgroundTag":"missing-required-argument","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"}