spring-projects/spring-framework · error · IntrospectionException

Non int index to indexed write method: {}

Error message

Non int index to indexed write method: {}

What it means

Thrown by Spring's PropertyDescriptorUtils when introspecting a JavaBean indexed property whose indexed write method (setter) does not take an int as its first parameter. JavaBeans requires an indexed setter to have the signature setX(int index, Type value); any other first-argument type (long, Long, etc.) is rejected. Spring throws IntrospectionException (a checked exception from java.beans) so bean wiring aborts.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/PropertyDescriptorUtils.java:217

			if (params.length != 1) {
				throw new IntrospectionException("Bad indexed read method arg count: " + indexedReadMethod);
			}
			if (params[0] != int.class) {
				throw new IntrospectionException("Non int index to indexed read method: " + indexedReadMethod);
			}
			indexedPropertyType = indexedReadMethod.getReturnType();
			if (indexedPropertyType == void.class) {
				throw new IntrospectionException("Indexed read method returns void: " + indexedReadMethod);
			}
		}

		if (indexedWriteMethod != null) {
			Class<?>[] params = indexedWriteMethod.getParameterTypes();
			if (params.length != 2) {
				throw new IntrospectionException("Bad indexed write method arg count: " + indexedWriteMethod);
			}
			if (params[0] != int.class) {
				throw new IntrospectionException("Non int index to indexed write method: " + indexedWriteMethod);
			}
			if (indexedPropertyType != null) {
				if (indexedPropertyType.isAssignableFrom(params[1])) {
					// Write method's property type potentially more specific
					indexedPropertyType = params[1];
				}
				else if (params[1].isAssignableFrom(indexedPropertyType)) {
					// Proceed with read method's property type
				}
				else {
					throw new IntrospectionException("Type mismatch between indexed read and write methods: " +
							indexedReadMethod + " - " + indexedWriteMethod);
				}
			}
			else {
				indexedPropertyType = params[1];
			}
		}

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Change the indexed setter's first parameter to int: setX(int index, Type value).
  2. If the method is not meant to be an indexed setter, rename it so it does not collide with the getX(int)/setX(int, ...) convention.
  3. If you truly need a long index, do not expose it as a JavaBeans indexed property; provide a plain setter and handle indexing internally.

Example fix

// before
public void setItem(long index, Item item) { this.items[(int) index] = item; }

// after
public void setItem(int index, Item item) { this.items[index] = item; }
Defensive patterns

Strategy: validation

Validate before calling

// Verify an indexed setter uses int before exposing the bean to Spring
Method m = beanClass.getDeclaredMethod("setItem", long.class, Object.class);
throw new IllegalStateException("setItem must take int index, not long");

Type guard

// Indexed setter shape guard for JavaBeans
static boolean isValidIndexedSetter(Method m) {
    Class<?>[] p = m.getParameterTypes();
    return m.getName().startsWith("set") && p.length == 2 && p[0] == int.class;
}

Prevention

When it happens

Trigger: Calling BeanWrapperImpl / CachedIntrospectionResults on a class that has a method matching the setX(int?, ...) indexed-setter naming convention but whose first parameter is not exactly int.class (e.g. setItem(long, String)). Triggered during getDeclaredMethods introspection in findIndexedPropertyType() at line 216.

Common situations: A developer names a helper method like setPosition(long index, Value) on a bean that is later injected/bound by Spring; or uses a wrapper type (Long) for the index thinking it is equivalent to int. Also surfaces after refactoring a collection indexed access where the index field type was widened to long.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/15839f8a858ed827. Report an issue: GitHub.