spring-projects/spring-framework · error · NullValueInNestedPathException

Could not determine property type for auto-growing a default

Error message

Could not determine property type for auto-growing a default value

What it means

Thrown as NullValueInNestedPathException during auto-growing when getPropertyTypeDescriptor(canonicalName) returns null, meaning Spring cannot determine the Java type to instantiate for the missing nested segment. Without a type, newValue(...) cannot create a default, so the auto-grow attempt fails even though auto-grow is enabled.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java:871

			if (logger.isTraceEnabled()) {
				logger.trace("Using cached nested property accessor for property '" + canonicalName + "'");
			}
		}
		return nestedPa;
	}

	private Object setDefaultValue(PropertyTokenHolder tokens) {
		PropertyValue pv = createDefaultPropertyValue(tokens);
		setPropertyValue(tokens, pv);
		Object defaultValue = getPropertyValue(tokens);
		Assert.state(defaultValue != null, "Default value must not be null");
		return defaultValue;
	}

	private PropertyValue createDefaultPropertyValue(PropertyTokenHolder tokens) {
		TypeDescriptor desc = getPropertyTypeDescriptor(tokens.canonicalName);
		if (desc == null) {
			throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + tokens.canonicalName,
					"Could not determine property type for auto-growing a default value");
		}
		Object defaultValue = newValue(desc.getType(), desc, tokens.canonicalName);
		return new PropertyValue(tokens.canonicalName, defaultValue);
	}

	private Object newValue(Class<?> type, @Nullable TypeDescriptor desc, String name) {
		try {
			if (type.isArray()) {
				return createArray(type);
			}
			else if (Collection.class.isAssignableFrom(type)) {
				TypeDescriptor elementDesc = (desc != null ? desc.getElementTypeDescriptor() : null);
				return CollectionFactory.createCollection(type, (elementDesc != null ? elementDesc.getType() : null), 16);
			}
			else if (Map.class.isAssignableFrom(type)) {
				TypeDescriptor keyDesc = (desc != null ? desc.getMapKeyTypeDescriptor() : null);
				return CollectionFactory.createMap(type, (keyDesc != null ? keyDesc.getType() : null), 16);

View on GitHub (pinned to e8729d0438)

Solutions

  1. Add a concrete field type and matching getter/setter so a TypeDescriptor is available (e.g. private Address address; with getAddress/setAddress).
  2. Verify the property path spelling matches a real, introspectable bean property.
  3. Disable autoGrowNestedPaths and instead pre-initialize the nested object, so the type-descriptor path is never taken.
  4. Parameterize generic collections/maps explicitly (List<Address> not List) so element types resolve.

Example fix

// before
public class Order { private Object address; } // type unknowable
BeanWrapper w = new BeanWrapperImpl(order);
w.setAutoGrowNestedPaths(true);
w.setPropertyValue("address.city", "NYC"); // type descriptor null

// after
public class Order { private Address address; // + getter/setter }
Defensive patterns

Strategy: validation

Validate before calling

// Confirm a TypeDescriptor is resolvable before relying on auto-grow
BeanWrapper w = new BeanWrapperImpl(target);
w.setAutoGrowNestedPaths(true);
TypeDescriptor td = null;
try { td = ((AbstractNestablePropertyAccessor) w).getPropertyTypeDescriptor(propName); }
catch (Exception ignored) {}
if (td == null) { /* do not auto-grow; initialize manually */ }

Type guard

public static boolean hasResolvableTypeDescriptor(BeanWrapper w, String prop) {
  try { return w.getPropertyTypeDescriptor(prop) != null; }
  catch (Exception e) { return false; }
}

Try / catch

try {
  wrapper.setAutoGrowNestedPaths(true);
  wrapper.setPropertyValue(path, value);
} catch (NullValueInNestedPathException e) {
  if (e.getMessage().contains("auto-growing")) { /* initialize nested field manually */ }
}

Prevention

When it happens

Trigger: autoGrowNestedPaths=true and binding into a property whose type is unresolvable: a raw-typed field, an unparameterized Object/Map element, a property with no read/write accessor, or a property name not present on the target class. Occurs inside createDefaultPropertyValue at AbstractNestablePropertyAccessor.java:868-873.

Common situations: Binding into Map<String,Object>-style loosely typed targets. Properties files / YAML mapping to a field whose getter/setter was removed or renamed. Generic base classes where erasure leaves the element type unknown. Typos in the property path that don't match any descriptor.

Related errors


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