spring-projects/spring-framework · error · IntrospectionException

Type mismatch between indexed read and write methods: ${inde

Error message

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

What it means

IntrospectionException from PropertyDescriptorUtils.findIndexedPropertyType when the indexed read method's return type and the indexed write method's second parameter type are mutually non-assignable. Indexed accessors must agree on element type; if neither is assignable to the other the indexed property has an inconsistent type.

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 e8729d0438)

Solutions

  1. Align the indexed getter return type and the indexed setter's value parameter to the same element type.
  2. If a more specific setter is intended, ensure the setter value type is assignable from the getter return type.
  3. Regenerate accessors after type changes.

Example fix

// before
public Number getItem(int i) { ... }
public void setItem(int i, String v) { ... }

// after
public Number getItem(int i) { ... }
public void setItem(int i, Number v) { ... }
Defensive patterns

Strategy: type-guard

Validate before calling

static void assertIndexedReadWriteTypesMatch(Method r, Method w) {
    Class<?> rt = r.getReturnType();
    Class<?> wt = w.getParameterTypes()[1];
    if (!rt.isAssignableFrom(wt) && !wt.isAssignableFrom(rt)) {
        throw new IllegalStateException("Indexed getter returns " + rt + " setter takes " + wt);
    }
}

Type guard

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

Try / catch

try {
    return new IndexedPropertyDescriptor(name, null, null, r, w);
} catch (java.beans.IntrospectionException ex) {
    if (ex.getMessage().startsWith("Type mismatch between indexed read and write")) {
        log.error("Fix indexed pair: get returns {} set takes {}", r.getReturnType(), w.getParameterTypes()[1]);
    }
    throw ex;
}

Prevention

When it happens

Trigger: getX(int) returns type A, setX(int, B) takes type B with A and B unrelated; refactor changed the element type on one side only.

Common situations: Refactor of generic element types; copy-paste accessor pairs with mismatched generics; covariant return on indexed getter not reflected in indexed setter.

Related errors


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/ffca9f8b1b1af692.json. Report an issue: GitHub.