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

  1. Validate readability of each intermediate segment with isReadableProperty before the indexed write.
  2. Expose a getter for the intermediate property so Spring can navigate it.
  3. Restructure the path or pre-populate the intermediate container so the holding value is reachable.
  4. 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

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


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)