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

  1. Inspect the nested path segment named in the message and confirm the corresponding getter exists on the enclosing bean.
  2. Correct typos in the property path string (use the actual field/property name).
  3. If the intermediate can legitimately be null at bind time, call setAutoGrowNestedPaths(true) or initialize the nested object before binding.
  4. 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

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


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/e2a25f35944326cc.json. Report an issue: GitHub.