{"id":"e4b24038ea3a53f6","repo":"spring-projects/spring-framework","slug":"cannot-access-indexed-value-in-property-referenced","errorCode":null,"errorMessage":"Cannot access indexed value in property referenced in indexed property path '{tokens.canonicalName}'","messagePattern":"Cannot access indexed value in property referenced in indexed property path '(.+?)'","errorType":"exception","errorClass":"NotWritablePropertyException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java","lineNumber":373,"sourceCode":"\t\t\t\t\t\"Property referenced in indexed property path '\" + tokens.canonicalName +\n\t\t\t\t\t\"' is neither an array nor a List nor a Map; returned value was [\" + propValue + \"]\");\n\t\t}\n\t}\n\n\tprivate Object getPropertyHoldingValue(PropertyTokenHolder tokens) {\n\t\t// Apply indexes and map keys: fetch value for all keys but the last one.\n\t\tAssert.state(tokens.keys != null, \"No token keys\");\n\t\tPropertyTokenHolder getterTokens = new PropertyTokenHolder(tokens.actualName);\n\t\tgetterTokens.canonicalName = tokens.canonicalName;\n\t\tgetterTokens.keys = new String[tokens.keys.length - 1];\n\t\tSystem.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);\n\n\t\tObject propValue;\n\t\ttry {\n\t\t\tpropValue = getPropertyValue(getterTokens);\n\t\t}\n\t\tcatch (NotReadablePropertyException ex) {\n\t\t\tthrow new NotWritablePropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,\n\t\t\t\t\t\"Cannot access indexed value in property referenced \" +\n\t\t\t\t\t\"in indexed property path '\" + tokens.canonicalName + \"'\", ex);\n\t\t}\n\n\t\tif (propValue == null) {\n\t\t\t// null map value case\n\t\t\tif (isAutoGrowNestedPaths()) {\n\t\t\t\tint lastKeyIndex = tokens.canonicalName.lastIndexOf('[');\n\t\t\t\tgetterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);\n\t\t\t\tpropValue = setDefaultValue(getterTokens);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new NullValueInNestedPathException(getRootClass(), this.nestedPath + tokens.canonicalName,\n\t\t\t\t\t\t\"Cannot access indexed value in property referenced \" +\n\t\t\t\t\t\t\"in indexed property path '\" + tokens.canonicalName + \"': returned null\");\n\t\t\t}\n\t\t}\n\t\treturn propValue;","sourceCodeStart":355,"sourceCodeEnd":391,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java#L355-L391","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Expose a readable getter for the property that holds the inner collection/array/map.","Correct the nested indexed path so each segment resolves to a real readable property.","Pre-initialize the holder and make sure its visibility allows reflection access."],"exampleFix":"// before\npublic class Grid { private int[][] cells; int[][] getCells() { return cells; } } // package-private getter\nwrapper.setPropertyValue(\"cells[0][1]\", 5);\n\n// after\npublic int[][] getCells() { return cells; } // public getter","handlingStrategy":"validation","validationCode":"String base = path.replaceAll(\"\\\\[.*$\", \"\");\nif (wrapper.isReadableProperty(base)) {\n    wrapper.setPropertyValue(path, value);\n}","typeGuard":"static boolean holderReadable(BeanWrapper bw, String path) {\n    return bw.isReadableProperty(path.replaceAll(\"\\\\[.*$\", \"\"));\n}","tryCatchPattern":"try { wrapper.setPropertyValue(path, value); }\ncatch (NotWritablePropertyException ex) { /* expose a getter for the holder */ }","preventionTips":["Ensure each intermediate collection property has a public getter.","Keep getter visibility public for beans used with BeanWrapper."],"tags":["spring-beans","bean-wrapper","indexed-property","nested-property","not-readable"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}