{"id":"e2a25f35944326cc","repo":"spring-projects/spring-framework","slug":"nested-property-in-path-propertyname-does-not","errorCode":null,"errorMessage":"Nested property in path '{propertyName}' does not exist","messagePattern":"Nested property in path '(.+?)' does not exist","errorType":"exception","errorClass":"NotWritablePropertyException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java","lineNumber":222,"sourceCode":"\t\treturn this.rootObject;\n\t}\n\n\t/**\n\t * Return the class of the root object at the top of the path of this accessor.\n\t * @see #getNestedPath\n\t */\n\tpublic final Class<?> getRootClass() {\n\t\treturn getRootInstance().getClass();\n\t}\n\n\t@Override\n\tpublic void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {\n\t\tAbstractNestablePropertyAccessor nestedPa;\n\t\ttry {\n\t\t\tnestedPa = getPropertyAccessorForPropertyPath(propertyName);\n\t\t}\n\t\tcatch (NotReadablePropertyException ex) {\n\t\t\tthrow new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,\n\t\t\t\t\t\"Nested property in path '\" + propertyName + \"' does not exist\", ex);\n\t\t}\n\t\tPropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));\n\t\tnestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value));\n\t}\n\n\t@Override\n\tpublic void setPropertyValue(PropertyValue pv) throws BeansException {\n\t\tPropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;\n\t\tif (tokens == null) {\n\t\t\tString propertyName = pv.getName();\n\t\t\tAbstractNestablePropertyAccessor nestedPa;\n\t\t\ttry {\n\t\t\t\tnestedPa = getPropertyAccessorForPropertyPath(propertyName);\n\t\t\t}\n\t\t\tcatch (NotReadablePropertyException ex) {\n\t\t\t\tthrow new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,\n\t\t\t\t\t\t\"Nested property in path '\" + propertyName + \"' does not exist\", ex);","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java#L204-L240","documentation":"Thrown by setPropertyValue(String, Object) when navigating a nested path such as 'a.b.c'. Spring walks the path by reading each intermediate segment via getPropertyAccessorForPropertyPath; if an intermediate segment has no readable property a NotReadablePropertyException is raised internally and rewrapped here as a NotWritablePropertyException. So the failure is about an intermediate hop being unreadable/non-existent, even though the operation requested is a write.","triggerScenarios":"beanWrapper.setPropertyValue(\"customer.address.city\", value) where getCustomer() exists but Address has no getCity()/setCity(); a typo in a SpEL/BeanWrapper path used for binding; binding a form field whose path references a property removed in a refactor.","commonSituations":"Spring MVC form binding to nested command objects; @ConfigurationProperties with a misspelled nested key; JSON/YAML deserialization via BeanWrapper where an intermediate bean is missing a getter.","solutions":["Inspect the nested path segment named in the message and confirm the corresponding getter exists on the enclosing bean.","Correct typos in the property path string (use the actual field/property name).","If the intermediate can legitimately be null at bind time, call setAutoGrowNestedPaths(true) or initialize the nested object before binding.","For binding from untrusted input, set ignoreUnknownFields/suppressNotWritablePropertyException so unknown segments are skipped."],"exampleFix":"// before\nwrapper.setPropertyValue(\"customer.adress.city\", \"Berlin\"); // typo 'adress'\n\n// after\nwrapper.setPropertyValue(\"customer.address.city\", \"Berlin\");","handlingStrategy":"validation","validationCode":"String path = \"customer.address.city\";\nif (wrapper.isWritableProperty(path)) {\n    wrapper.setPropertyValue(path, value);\n}","typeGuard":"static boolean allSegmentsExist(BeanWrapper bw, String path) {\n    for (String seg = path; seg != null && !seg.isEmpty(); ) {\n        int dot = seg.indexOf('.');\n        String head = dot < 0 ? seg : seg.substring(0, dot);\n        if (!bw.isReadableProperty(head)) return false;\n        seg = dot < 0 ? null : seg.substring(dot + 1);\n    }\n    return true;\n}","tryCatchPattern":"try {\n    wrapper.setPropertyValue(path, value);\n} catch (NotWritablePropertyException ex) {\n    if (ignoreUnknown) { /* skip */ } else throw ex;\n}","preventionTips":["Validate paths with isWritableProperty before binding.","Enable autoGrowNestedPaths when null intermediates are expected.","Use ignoreUnknownFields=true for loose external binding."],"tags":["spring-beans","bean-wrapper","nested-property","binding"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}