spring-projects/spring-framework · error · NotWritablePropertyException
Nested property in path '{propertyName}' does not exist
Error message
Nested property in path '{propertyName}' does not exist What it means
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.
Source
Thrown at spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java:222
return this.rootObject;
}
/**
* Return the class of the root object at the top of the path of this accessor.
* @see #getNestedPath
*/
public final Class<?> getRootClass() {
return getRootInstance().getClass();
}
@Override
public void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {
AbstractNestablePropertyAccessor nestedPa;
try {
nestedPa = getPropertyAccessorForPropertyPath(propertyName);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Nested property in path '" + propertyName + "' does not exist", ex);
}
PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
nestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value));
}
@Override
public void setPropertyValue(PropertyValue pv) throws BeansException {
PropertyTokenHolder tokens = (PropertyTokenHolder) pv.resolvedTokens;
if (tokens == null) {
String propertyName = pv.getName();
AbstractNestablePropertyAccessor nestedPa;
try {
nestedPa = getPropertyAccessorForPropertyPath(propertyName);
}
catch (NotReadablePropertyException ex) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
"Nested property in path '" + propertyName + "' does not exist", ex);View on GitHub (pinned to e8729d0438)
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.
Example fix
// before
wrapper.setPropertyValue("customer.adress.city", "Berlin"); // typo 'adress'
// after
wrapper.setPropertyValue("customer.address.city", "Berlin"); Defensive patterns
Strategy: validation
Validate before calling
String path = "customer.address.city";
if (wrapper.isWritableProperty(path)) {
wrapper.setPropertyValue(path, value);
} Type guard
static boolean allSegmentsExist(BeanWrapper bw, String path) {
for (String seg = path; seg != null && !seg.isEmpty(); ) {
int dot = seg.indexOf('.');
String head = dot < 0 ? seg : seg.substring(0, dot);
if (!bw.isReadableProperty(head)) return false;
seg = dot < 0 ? null : seg.substring(dot + 1);
}
return true;
} Try / catch
try {
wrapper.setPropertyValue(path, value);
} catch (NotWritablePropertyException ex) {
if (ignoreUnknown) { /* skip */ } else throw ex;
} Prevention
- Validate paths with isWritableProperty before binding.
- Enable autoGrowNestedPaths when null intermediates are expected.
- Use ignoreUnknownFields=true for loose external binding.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Value of nested property '${nestedPath}${canonicalName}' is
- Cannot access indexed value in property referenced in indexe
- Could not determine property type for auto-growing a default
- No property handler found
- Invalid array index in property path '{tokens.canonicalName}
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/e2a25f35944326cc.json.
Report an issue: GitHub.