spring-projects/spring-framework · error · NotWritablePropertyException
Cannot access indexed value in property referenced in…
Error message
Cannot access indexed value in property referenced in indexed property path '{tokens.canonicalName}' What it means
Thrown by getPropertyHoldingValue when resolving the parent value of a multi-key indexed path (all keys except the last) raises NotReadablePropertyException. It is rethrown as NotWritablePropertyException, signalling the intermediate/holding property cannot be read so the keyed write cannot proceed.
Solutions
- Validate readability of each intermediate segment with isReadableProperty before the indexed write.
- Expose a getter for the intermediate property so Spring can navigate it.
- Restructure the path or pre-populate the intermediate container so the holding value is reachable.
- Enable autoGrowNestedPaths so missing intermediates are created where the type allows.
Example fix
// before
wrapper.setPropertyValue("grid[0][1]", v); // grid[0] not readable
// after
// ensure getGrid() returns a List<List<T>> with a readable inner list
wrapper.setPropertyValue("grid[0][1]", v); Defensive patterns
Strategy: validation
Validate before calling
BeanWrapper w = new BeanWrapperImpl(bean);
// for path a[i][j], ensure a[i] is readable
String intermediate = path.substring(0, path.lastIndexOf('['));
if (!w.isReadableProperty(intermediate)) {
throw new IllegalArgumentException("intermediate not readable: " + intermediate);
}
w.setPropertyValue(path, value); Type guard
static boolean intermediateReadable(BeanWrapper w, String fullPath) {
int last = fullPath.lastIndexOf('[');
String inter = last < 0 ? fullPath : fullPath.substring(0, last);
return w.isReadableProperty(inter);
} Try / catch
try {
wrapper.setPropertyValue(path, value);
} catch (NotWritablePropertyException ex) {
if (ex.getMessage().contains("Cannot access indexed value")) { /* expose getter or pre-create intermediate */ }
else throw ex;
} Prevention
- Expose readable getters for all intermediate container properties.
- Pre-populate nested containers so intermediates are never null/private.
- Test deep indexed paths in unit tests against the real bean graph.
When it happens
Trigger: setProperty("matrix[0][1]", value) or setProperty("map[key].field", value) where an intermediate segment ('matrix[0]' or 'map[key]') is not readable on its owner.
Common situations: A nested container whose intermediate element has no getter; binding a deeply indexed path onto a structure where the middle object is null/private; refactored nested types breaking the intermediate read.
Related errors
- Cannot access indexed value in property referenced in…
- Cannot access indexed value of property referenced in…
- Nested property in path
- No property handler found
- Property referenced in indexed property path
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/e4b24038ea3a53f6.
Report an issue: GitHub.
Appendix: source
Thrown at spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java:373
"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) {
throw new NotWritablePropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + tokens.canonicalName + "'", ex);
}
if (propValue == null) {
// null map value case
if (isAutoGrowNestedPaths()) {
int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
propValue = setDefaultValue(getterTokens);
}
else {
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + tokens.canonicalName,
"Cannot access indexed value in property referenced " +
"in indexed property path '" + tokens.canonicalName + "': returned null");
}
}
return propValue;View on GitHub (pinned to 69bf83ad71)