{"id":"84494e4436ee035e","repo":"spring-projects/spring-framework","slug":"cannot-access-indexed-value-in-property-referenced-84494e","errorCode":null,"errorMessage":"Cannot access indexed value in property referenced in indexed property path '{tokens.canonicalName}': returned null","messagePattern":"Cannot access indexed value in property referenced in indexed property path '(.+?)': returned null","errorType":"exception","errorClass":"NullValueInNestedPathException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java","lineNumber":386,"sourceCode":"\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;\n\t}\n\n\tprivate void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {\n\t\tPropertyHandler ph = getLocalPropertyHandler(tokens.actualName);\n\t\tif (ph == null || !ph.isWritable()) {\n\t\t\tif (pv.isOptional()) {\n\t\t\t\tif (logger.isDebugEnabled()) {\n\t\t\t\t\tlogger.debug(\"Ignoring optional value for property '\" + tokens.actualName +\n\t\t\t\t\t\t\t\"' - property not found on bean class [\" + getRootClass().getName() + \"]\");\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.suppressNotWritablePropertyException) {","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/e8729d043887bf0d0baf91e062e909b56eb2b708/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java#L368-L404","documentation":"Thrown by getPropertyHoldingValue when the resolved holder for an indexed/mapped write is null and autoGrowNestedPaths is disabled. Without auto-grow Spring cannot follow the index, so it raises NullValueInNestedPathException with 'returned null'. The canonical path in the message is the full indexed expression being written.","triggerScenarios":"setProperty(\"items[0]\", x) where getItems() returns null and autoGrowNestedPaths is false; binding into a map[key] sub-path where the enclosing map is null; writing to a nested indexed property on a freshly constructed bean whose collections are not initialized.","commonSituations":"BeanWrapper used without enabling auto-grow on beans with uninitialized collection fields; binding request data onto POJOs whose fields default to null; @ConfigurationProperties with a null map before population.","solutions":["Enable wrapper.setAutoGrowNestedPaths(true) so null holders are created automatically.","Initialize the collection/map/array field in the bean constructor or field initializer.","Pre-populate the holder before performing the indexed write."],"exampleFix":"// before\npublic class Order { private List<Item> items; ... } // null by default\nwrapper.setPropertyValue(\"items[0]\", item);\n\n// after\npublic class Order { private List<Item> items = new ArrayList<>(); ... }","handlingStrategy":"validation","validationCode":"Object holder = wrapper.getPropertyValue(path.replaceAll(\"\\\\[.*$\", \"\"));\nif (holder != null || wrapper.isAutoGrowNestedPaths()) {\n    wrapper.setPropertyValue(path, value);\n}","typeGuard":"static boolean holderReady(BeanWrapper bw, String path) {\n    Object h = bw.getPropertyValue(path.replaceAll(\"\\\\[.*$\", \"\"));\n    return h != null || bw.isAutoGrowNestedPaths();\n}","tryCatchPattern":"try { wrapper.setPropertyValue(path, value); }\ncatch (NullValueInNestedPathException ex) { /* initialize holder then retry */ }","preventionTips":["Initialize collection/map/array fields in constructors or field initializers.","Enable autoGrowNestedPaths when binders may hit null holders."],"tags":["spring-beans","bean-wrapper","indexed-property","null-value","auto-grow"],"analyzedSha":"e8729d043887bf0d0baf91e062e909b56eb2b708","analyzedAt":"2026-08-04T19:07:39.725Z","schemaVersion":2}