{"record":{"id":"817b308e60f802df","repo":"spring-projects/spring-framework","slug":"invalid-property-propertyname-of-bean-class-817b30","errorCode":null,"errorMessage":"Invalid property '{propertyName}' of bean class [{beanClass.getName()}]: Value of nested property '{propertyName}' is null","messagePattern":"Invalid property '(.+?)' of bean class \\[(.+?)\\]: Value of nested property '(.+?)' is null","errorType":"exception","errorClass":"NullValueInNestedPathException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java","lineNumber":836,"sourceCode":"\t * @param nestedProperty property to create the PropertyAccessor for\n\t * @return the PropertyAccessor instance, either cached or newly created\n\t */\n\tprivate AbstractNestablePropertyAccessor getNestedPropertyAccessor(String nestedProperty) {\n\t\tMap<String, AbstractNestablePropertyAccessor> nestedAccessors = this.nestedPropertyAccessors;\n\t\tif (nestedAccessors == null) {\n\t\t\tnestedAccessors = new HashMap<>();\n\t\t\tthis.nestedPropertyAccessors = nestedAccessors;\n\t\t}\n\t\t// Get value of bean property.\n\t\tPropertyTokenHolder tokens = getPropertyNameTokens(nestedProperty);\n\t\tString canonicalName = tokens.canonicalName;\n\t\tObject value = getPropertyValue(tokens);\n\t\tif (value == null || (value instanceof Optional<?> optional && optional.isEmpty())) {\n\t\t\tif (isAutoGrowNestedPaths()) {\n\t\t\t\tvalue = setDefaultValue(tokens);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new NullValueInNestedPathException(getRootClass(), this.nestedPath + canonicalName);\n\t\t\t}\n\t\t}\n\n\t\t// Lookup cached sub-PropertyAccessor, create new one if not found.\n\t\tAbstractNestablePropertyAccessor nestedPa = nestedAccessors.get(canonicalName);\n\t\tif (nestedPa == null || nestedPa.getWrappedInstance() != ObjectUtils.unwrapOptional(value)) {\n\t\t\tif (logger.isTraceEnabled()) {\n\t\t\t\tlogger.trace(\"Creating new nested \" + getClass().getSimpleName() + \" for property '\" + canonicalName + \"'\");\n\t\t\t}\n\t\t\tnestedPa = newNestedPropertyAccessor(value, this.nestedPath + canonicalName + NESTED_PROPERTY_SEPARATOR);\n\t\t\t// Inherit all type-specific PropertyEditors.\n\t\t\tcopyDefaultEditorsTo(nestedPa);\n\t\t\tcopyCustomEditorsTo(nestedPa, canonicalName);\n\t\t\tnestedAccessors.put(canonicalName, nestedPa);\n\t\t}\n\t\telse {\n\t\t\tif (logger.isTraceEnabled()) {\n\t\t\t\tlogger.trace(\"Using cached nested property accessor for property '\" + canonicalName + \"'\");","sourceCodeStart":818,"sourceCodeEnd":854,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java#L818-L854","documentation":"Thrown as NullValueInNestedPathException (subclass of InvalidPropertyException) by getNestedPropertyAccessor at AbstractNestablePropertyAccessor.java:836 when navigating a nested property path and an intermediate property resolves to null while autoGrowNestedPaths is disabled. The default message 'Value of nested property ... is null' comes from the NullValueInNestedPathException(beanClass, propertyName) constructor.","triggerScenarios":"Reading or writing a nested path such as 'spouse.age' or 'address.city' via BeanWrapper/PropertyAccessor when the intermediate 'spouse' or 'address' property is null and setAutoGrowNestedPaths(false) (the default). Also triggered when an intermediate Optional is empty (line 831 handles Optional.empty).","commonSituations":"Spring data binding from a form/JSON where only a leaf field is provided but the parent object is never initialized; @ConfigurationProperties binding into a DTO with nested objects that have no default initializer; SpEL/path traversal over a freshly constructed bean; entity graphs where a relation is lazily null.","solutions":["Initialize the nested reference in the bean's field declaration or constructor (e.g. 'private Address address = new Address();').","Enable auto-growing: beanWrapper.setAutoGrowNestedPaths(true); to have Spring instantiate null intermediate beans.","Provide the full nested object graph in the input rather than only the leaf value.","Validate the path with isReadableProperty/getPropertyType before traversal and skip if the parent is null."],"exampleFix":"// before\npublic class Person {\n    private Address address; // null\n}\n\n// after\npublic class Person {\n    private Address address = new Address();\n}","handlingStrategy":"validation","validationCode":"// Pre-check that every intermediate segment is non-null\nBeanWrapper w = new BeanWrapperImpl(target);\nif (w.isAutoGrowNestedPaths() || intermediateNotNull(w, path)) {\n    w.getPropertyValue(path);\n}\nstatic boolean intermediateNotNull(BeanWrapper w, String path) {\n    String[] segs = path.split(\"\\\\.\");\n    Object cur = w.getWrappedInstance();\n    BeanWrapper tmp = new BeanWrapperImpl(cur);\n    for (String s : segs) {\n        cur = tmp.getPropertyValue(s);\n        if (cur == null) return false;\n        tmp = new BeanWrapperImpl(cur);\n    }\n    return true;\n}","typeGuard":"static boolean canNavigate(Object root, String path) {\n    try {\n        Object cur = root;\n        for (String s : path.split(\"\\\\.\")) {\n            cur = new BeanWrapperImpl(cur).getPropertyValue(s);\n            if (cur == null) return false;\n        }\n        return true;\n    } catch (BeansException e) { return false; }\n}","tryCatchPattern":"try {\n    wrapper.getPropertyValue(\"spouse.age\");\n} catch (NullValueInNestedPathException ex) {\n    // ex.getPropertyName() tells you which segment was null\n    // decide: skip, default, or enable auto-grow\n    wrapper.setAutoGrowNestedPaths(true);\n}","preventionTips":["Initialize nested fields inline: 'private Address address = new Address();'.","Enable setAutoGrowNestedPaths(true) when binding form data with sparse parents.","Use isReadableProperty/getPropertyType to verify paths before traversal.","Keep nested types as concrete instantiable classes with no-arg constructors."],"tags":["spring-beans","beanwrapper","nested-property","null","auto-grow"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}