spring-projects/spring-framework · error · InvalidPropertyException
Property referenced in indexed property path '{tokens.canoni
Error message
Property referenced in indexed property path '{tokens.canonicalName}' is neither an array nor a List nor a Map; returned value was [{propValue}] What it means
Thrown in the final else of processKeyedProperty: the property path uses index/map syntax (e.g. 'foo[0]' or 'foo[key]') but the resolved value is not an array, List, or Map. Because there is no keyed access possible, Spring raises InvalidPropertyException naming the canonical path and showing the offending value.
Source
Thrown at spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java:354
TypeDescriptor mapKeyType = ph.getMapKeyType(tokens.keys.length);
TypeDescriptor mapValueType = ph.getMapValueType(tokens.keys.length);
// IMPORTANT: Do not pass full property name in here - property editors
// must not kick in for map keys but rather only for map values.
Object convertedMapKey = convertIfNecessary(null, null, lastKey,
mapKeyType.getResolvableType().resolve(), mapKeyType);
Object oldValue = null;
if (isExtractOldValueForEditor()) {
oldValue = map.get(convertedMapKey);
}
// Pass full property name and old value in here, since we want full
// conversion ability for map values.
Object convertedMapValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),
mapValueType.getResolvableType().resolve(), mapValueType);
map.put(convertedMapKey, convertedMapValue);
}
else {
throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Property referenced in indexed property path '" + tokens.canonicalName +
"' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
}
}
private Object getPropertyHoldingValue(PropertyTokenHolder tokens) {
// Apply indexes and map keys: fetch value for all keys but the last one.
Assert.state(tokens.keys != null, "No token keys");
PropertyTokenHolder getterTokens = new PropertyTokenHolder(tokens.actualName);
getterTokens.canonicalName = tokens.canonicalName;
getterTokens.keys = new String[tokens.keys.length - 1];
System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
Object propValue;
try {
propValue = getPropertyValue(getterTokens);
}
catch (NotReadablePropertyException ex) {View on GitHub (pinned to e8729d0438)
Solutions
- Change the bean property to an array, List, or Map so indexed/mapped writes are valid.
- Remove the index/bracket from the path if the target is genuinely scalar.
- Re-check the path spelling and ensure the intended collection property is being addressed.
Example fix
// before
public class Cart { private int itemCount; ... }
wrapper.setPropertyValue("itemCount[0]", 1); // scalar, not indexable
// after
public class Cart { private List<Integer> itemCounts = new ArrayList<>(); ... }
wrapper.setPropertyValue("itemCounts[0]", 1); Defensive patterns
Strategy: type-guard
Validate before calling
Class<?> type = wrapper.getPropertyType("count");
if (type != null && (type.isArray() || List.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type))) {
wrapper.setPropertyValue("count[0]", value);
} Type guard
static boolean isIndexable(Class<?> type) {
return type != null && (type.isArray() || List.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type));
} Try / catch
try { wrapper.setPropertyValue(path, value); }
catch (InvalidPropertyException ex) { /* property is scalar; drop bracket */ } Prevention
- Check the property type is array/List/Map before applying bracket syntax.
- Keep binding paths consistent with the current model types.
When it happens
Trigger: setProperty("count[0]", x) where getCount() returns an int; binding 'name[key]' onto a String property; a path where the collection field was replaced by a scalar type in a refactor.
Common situations: Binding indexed form fields onto a bean whose property is a scalar after a model change; SpEL/BeanWrapper misuse applying brackets to non-collection fields; misconfigured @ConfigurationProperties mapping a list key onto a single-value field.
Related errors
- Property referenced in indexed property path '{propertyName}
- No property handler found
- Invalid array index in property path '{tokens.canonicalName}
- Cannot set element with index {index} in List of size {size}
- Invalid list index in property path '{tokens.canonicalName}'
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/0436f091d354c8fa.json.
Report an issue: GitHub.