spring-projects/spring-framework · error · IntrospectionException

Type mismatch between indexed read and write methods

Error message

Type mismatch between indexed read and write methods: {} - {}

What it means

Thrown when an indexed property has both an indexed read method (getX(int)) and an indexed write method (setX(int, T)) whose element types are mutually incompatible — neither is assignable to the other. This is the IntrospectionException raised at line 228, mirroring java.beans.IndexedPropertyDescriptor.findIndexedPropertyType. It prevents Spring from determining a single coherent property type.

Solutions

  1. Make the indexed getter's return type and the indexed setter's second-parameter type identical (or at least one assignable to the other).
  2. If the types genuinely differ, drop the conflicting method so only one indexed accessor remains.
  3. Regenerate accessors with the IDE so both use the same field type.

Example fix

// before
public String getItem(int i) { return items[i]; }
public void setItem(int i, Integer v) { items[i] = v; }

// after
public String getItem(int i) { return items[i]; }
public void setItem(int i, String v) { items[i] = v; }
Defensive patterns

Strategy: validation

Validate before calling

// Assert indexed read/write element types agree before binding
Class<?> readE = readMethod.getReturnType();
Class<?> writeE = writeMethod.getParameterTypes()[1];
if (!readE.isAssignableFrom(writeE) && !writeE.isAssignableFrom(readE)) {
    throw new IllegalStateException("indexed element types incompatible: " + readE + " vs " + writeE);
}

Type guard

static boolean indexedTypesAgree(Method read, Method write) {
    Class<?> r = read.getReturnType();
    Class<?> w = write.getParameterTypes()[1];
    return r.isAssignableFrom(w) || w.isAssignableFrom(r);
}

Prevention

When it happens

Trigger: A class declares e.g. String getItem(int i) and void setItem(int i, Integer value). In findIndexedPropertyType(), neither String.isAssignableFrom(Integer) nor Integer.isAssignableFrom(String) holds, so the mismatch branch throws.

Common situations: Copy-paste errors when generating getters/setters; mixing a read method that returns a String with a setter taking a numeric wrapper; legacy beans where the indexed getter/setter were written at different times with drifted types.

Related errors


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

Appendix: source

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

		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];
			}
		}

		if (propertyType != null && (!propertyType.isArray() ||
				propertyType.componentType() != indexedPropertyType)) {
			throw new IntrospectionException("Type mismatch between indexed and non-indexed methods: " +
					indexedReadMethod + " - " + indexedWriteMethod);
		}

		return indexedPropertyType;
	}

	/**

View on GitHub (pinned to 69bf83ad71)