{"id":"102f3f60d4975869","repo":"spring-projects/spring-framework","slug":"invalid-array-index-in-property-path-tokens-cano","errorCode":null,"errorMessage":"Invalid array index in property path '{tokens.canonicalName}'","messagePattern":"Invalid array index in property path '(.+?)'","errorType":"exception","errorClass":"InvalidPropertyException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java","lineNumber":295,"sourceCode":"\t\t\ttry {\n\t\t\t\tif (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {\n\t\t\t\t\toldValue = Array.get(propValue, arrayIndex);\n\t\t\t\t}\n\t\t\t\tObject convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),\n\t\t\t\t\t\tcomponentType, ph.nested(tokens.keys.length));\n\t\t\t\tint length = Array.getLength(propValue);\n\t\t\t\tif (arrayIndex >= length && arrayIndex < getAutoGrowCollectionLimit()) {\n\t\t\t\t\tObject newArray = Array.newInstance(componentType, arrayIndex + 1);\n\t\t\t\t\tSystem.arraycopy(propValue, 0, newArray, 0, length);\n\t\t\t\t\tint lastKeyIndex = tokens.canonicalName.lastIndexOf('[');\n\t\t\t\t\tString propName = tokens.canonicalName.substring(0, lastKeyIndex);\n\t\t\t\t\tsetPropertyValue(propName, newArray);\n\t\t\t\t\tpropValue = getPropertyValue(propName);\n\t\t\t\t}\n\t\t\t\tArray.set(propValue, arrayIndex, convertedValue);\n\t\t\t}\n\t\t\tcatch (IndexOutOfBoundsException ex) {\n\t\t\t\tthrow new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,\n\t\t\t\t\t\t\"Invalid array index in property path '\" + tokens.canonicalName + \"'\", ex);\n\t\t\t}\n\t\t}\n\n\t\telse if (propValue instanceof List list) {\n\t\t\tTypeDescriptor requiredType = ph.getCollectionType(tokens.keys.length);\n\t\t\tint index = Integer.parseInt(lastKey);\n\t\t\tObject oldValue = null;\n\t\t\tif (isExtractOldValueForEditor() && index < list.size()) {\n\t\t\t\toldValue = list.get(index);\n\t\t\t}\n\t\t\tObject convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),\n\t\t\t\t\trequiredType.getResolvableType().resolve(), requiredType);\n\t\t\tint size = list.size();\n\t\t\tif (index >= size && index < getAutoGrowCollectionLimit()) {\n\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);","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java#L277-L313","documentation":"Raised in the array branch of processKeyedProperty when Array.set(array, arrayIndex, value) throws IndexOutOfBoundsException. Auto-grow only expands the array when arrayIndex < getAutoGrowCollectionLimit(); beyond that limit (or when auto-grow is off) the raw Array.set fails and Spring rewraps it as InvalidPropertyException 'Invalid array index'. The index in the message is the one in the canonical path like 'items[123]'.","triggerScenarios":"setProperty(\"arr[150]\", x) on an array of length 10 with autoGrowCollectionLimit at its default of 128 (150 > 128 so no auto-grow); writing to an array index that does not exist and autoGrowNestedPaths is false; binding to an array-backed field where the incoming index exceeds both the array length and the auto-grow ceiling.","commonSituations":"Bounded auto-grow limit (default 128) being exceeded by large indices; binding spreadsheet/CSV row data to arrays; disabling autoGrowNestedPaths while still using indexed writes.","solutions":["Increase setAutoGrowCollectionLimit above the largest index you bind.","Pre-size the target array to fit the index before binding.","Prefer a List over an array if indices vary widely, so auto-grow can append.","Switch from indexed array writes to fully replacing the array."],"exampleFix":"// before\nwrapper.setAutoGrowCollectionLimit(128);\nwrapper.setPropertyValue(\"slots[200]\", true); // 200 > 128\n\n// after\nwrapper.setAutoGrowCollectionLimit(256);\nwrapper.setPropertyValue(\"slots[200]\", true);","handlingStrategy":"validation","validationCode":"int idx = 200;\nif (wrapper.isAutoGrowNestedPaths() && idx < wrapper.getAutoGrowCollectionLimit()) {\n    wrapper.setPropertyValue(\"slots[\" + idx + \"]\", true);\n} else if (Array.getLength(wrapper.getPropertyValue(\"slots\")) > idx) {\n    wrapper.setPropertyValue(\"slots[\" + idx + \"]\", true);\n} else throw new IllegalArgumentException(\"index too large\");","typeGuard":"static boolean indexWithinArrayOrGrowLimit(BeanWrapper bw, Object array, int idx) {\n    return Array.getLength(array) > idx || (bw.isAutoGrowNestedPaths() && idx < bw.getAutoGrowCollectionLimit());\n}","tryCatchPattern":"try { wrapper.setPropertyValue(\"slots[\" + idx + \"]\", v); }\ncatch (InvalidPropertyException ex) { /* resize array manually, retry */ }","preventionTips":["Set autoGrowCollectionLimit above your max index.","Pre-size arrays, or prefer List for variable indices.","Validate indices against array length before indexed writes."],"tags":["spring-beans","bean-wrapper","array","indexed-property","index-out-of-bounds"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}