spring-projects/spring-framework · error · NotWritablePropertyException

Cannot access indexed value in property referenced in indexe

Error message

Cannot access indexed value in property referenced in indexed property path '{tokens.canonicalName}'

What it means

Thrown by getPropertyHoldingValue while resolving all-but-the-last key of an indexed path during a write. The getter chain hit a NotReadablePropertyException (an intermediate segment has no readable getter) and Spring rewraps it as NotWritablePropertyException with 'Cannot access indexed value...'. It signals that the indexed write failed because the value holding the index cannot itself be read.

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 e8729d0438)

Solutions

  1. Expose a readable getter for the property that holds the inner collection/array/map.
  2. Correct the nested indexed path so each segment resolves to a real readable property.
  3. Pre-initialize the holder and make sure its visibility allows reflection access.

Example fix

// before
public class Grid { private int[][] cells; int[][] getCells() { return cells; } } // package-private getter
wrapper.setPropertyValue("cells[0][1]", 5);

// after
public int[][] getCells() { return cells; } // public getter
Defensive patterns

Strategy: validation

Validate before calling

String base = path.replaceAll("\\[.*$", "");
if (wrapper.isReadableProperty(base)) {
    wrapper.setPropertyValue(path, value);
}

Type guard

static boolean holderReadable(BeanWrapper bw, String path) {
    return bw.isReadableProperty(path.replaceAll("\\[.*$", ""));
}

Try / catch

try { wrapper.setPropertyValue(path, value); }
catch (NotWritablePropertyException ex) { /* expose a getter for the holder */ }

Prevention

When it happens

Trigger: setProperty("matrix[0][1]", v) where the row getter is missing; writing 'grid[row][col]' onto a bean whose getGrid() is package-private or absent; nested indexed paths where an intermediate collection property lacks a getter.

Common situations: Binding into nested arrays/maps where the outer accessor was made read-only; refactor that removed a getter needed to reach an inner collection; multi-dimensional data binding onto immutable DTOs.

Related errors


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