{"record":{"id":"b2d3c4ecf5852483","repo":"spring-projects/spring-framework","slug":"invalid-list-index-in-property-path-tokens-canon","errorCode":null,"errorMessage":"Invalid list index in property path '{tokens.canonicalName}'","messagePattern":"Invalid list index in property path '(.+?)'","errorType":"exception","errorClass":"InvalidPropertyException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java","lineNumber":329,"sourceCode":"\t\t\t\tfor (int i = size; i < index; i++) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tlist.add(null);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (NullPointerException ex) {\n\t\t\t\t\t\tthrow new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,\n\t\t\t\t\t\t\t\t\"Cannot set element with index \" + index + \" in List of size \" +\n\t\t\t\t\t\t\t\tsize + \", accessed using property path '\" + tokens.canonicalName +\n\t\t\t\t\t\t\t\t\"': List does not support filling up gaps with null elements\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlist.add(convertedValue);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttry {\n\t\t\t\t\tlist.set(index, convertedValue);\n\t\t\t\t}\n\t\t\t\tcatch (IndexOutOfBoundsException ex) {\n\t\t\t\t\tthrow new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,\n\t\t\t\t\t\t\t\"Invalid list index in property path '\" + tokens.canonicalName + \"'\", ex);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\telse if (propValue instanceof Map map) {\n\t\t\tTypeDescriptor mapKeyType = ph.getMapKeyType(tokens.keys.length);\n\t\t\tTypeDescriptor mapValueType = ph.getMapValueType(tokens.keys.length);\n\t\t\t// IMPORTANT: Do not pass full property name in here - property editors\n\t\t\t// must not kick in for map keys but rather only for map values.\n\t\t\tObject convertedMapKey = convertIfNecessary(null, null, lastKey,\n\t\t\t\t\tmapKeyType.getResolvableType().resolve(), mapKeyType);\n\t\t\tObject oldValue = null;\n\t\t\tif (isExtractOldValueForEditor()) {\n\t\t\t\toldValue = map.get(convertedMapKey);\n\t\t\t}\n\t\t\t// Pass full property name and old value in here, since we want full\n\t\t\t// conversion ability for map values.","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java#L311-L347","documentation":"Thrown by processKeyedProperty in the List branch when list.set(index, convertedValue) raises IndexOutOfBoundsException — the non-autogrow path (index < size fails and index >= autoGrowCollectionLimit, or autoGrow off). Spring wraps it as InvalidPropertyException with the canonical property name.","triggerScenarios":"setProperty(\"list[5]\", value) with autoGrow disabled (or index beyond the limit) on a list of size <= 5; i.e. trying to set an index that does not yet exist.","commonSituations":"autoGrowNestedPaths not set; binding a zero-based sequential form onto a freshly constructed empty list; binding indices beyond autoGrowCollectionLimit.","solutions":["Enable setAutoGrowNestedPaths(true) (and check autoGrowCollectionLimit) so the list extends to the index.","Pre-populate the list to at least index+1 elements before binding.","Validate the index against list.size() in a custom binder and reject the request if out of range.","Use a Map<Integer, T> for sparse/arbitrary indices."],"exampleFix":"// before\nList<String> items = new ArrayList<>(); // size 0\nwrapper.setPropertyValue(\"items[2]\", v); // IndexOutOfBounds\n\n// after\nwrapper.setAutoGrowNestedPaths(true);\nwrapper.setPropertyValue(\"items[2]\", v);","handlingStrategy":"validation","validationCode":"BeanWrapper w = new BeanWrapperImpl(bean);\nObject base = w.getPropertyValue(\"items\");\nif (base instanceof List<?> l && (idx < 0 || idx >= l.size())) {\n    w.setAutoGrowNestedPaths(true);\n}\nw.setPropertyValue(\"items[\" + idx + \"]\", value);","typeGuard":"static boolean inListBounds(Object list, int idx) {\n    return list instanceof List<?> l && idx >= 0 && idx < l.size();\n}","tryCatchPattern":"try {\n    wrapper.setPropertyValue(\"items[\" + idx + \"]\", v);\n} catch (InvalidPropertyException ex) {\n    if (ex.getCause() instanceof IndexOutOfBoundsException) { /* pre-size list or enable autogrow */ }\n    else throw ex;\n}","preventionTips":["Enable autoGrowNestedPaths when binding sequential indices onto empty lists.","Pre-populate lists to the required size before binding.","Validate index <= list.size() (or within autoGrowCollectionLimit) before the write."],"tags":["spring-beans","bean-wrapper","list","index-out-of-bounds"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}