spring-projects/spring-framework · error · IntrospectionException

Indexed read method returns void: ${indexedReadMethod}

Error message

Indexed read method returns void: ${indexedReadMethod}

What it means

IntrospectionException from PropertyDescriptorUtils.findIndexedPropertyType when an indexed read method returns void. An indexed getter must return the element type at the given index; void return provides no element type so the descriptor cannot be constructed.

Source

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

	/**
	 * See {@link java.beans.IndexedPropertyDescriptor#findIndexedPropertyType}.
	 */
	public static @Nullable Class<?> findIndexedPropertyType(String name, @Nullable Class<?> propertyType,
			@Nullable Method indexedReadMethod, @Nullable Method indexedWriteMethod) throws IntrospectionException {

		Class<?> indexedPropertyType = null;

		if (indexedReadMethod != null) {
			Class<?>[] params = indexedReadMethod.getParameterTypes();
			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

View on GitHub (pinned to e8729d0438)

Solutions

  1. Give the indexed getter a non-void return type matching the element type.
  2. If the method is a command, rename it so it isn't treated as an accessor.

Example fix

// before
public void getItems(int index) { /* evict */ }

// after
public String getItems(int index) { return items[index]; }
Defensive patterns

Strategy: validation

Validate before calling

static void assertIndexedReadReturnsValue(Method m) {
    if (m.getReturnType() == void.class) {
        throw new IllegalArgumentException("Indexed read must not return void: " + m);
    }
}

Type guard

static boolean indexedReadReturnsValue(Method m) {
    return m != null && m.getReturnType() != void.class;
}

Try / catch

try {
    return new IndexedPropertyDescriptor(name, null, null, indexedReadMethod, indexedWriteMethod);
} catch (java.beans.IntrospectionException ex) {
    if (ex.getMessage().startsWith("Indexed read method returns void")) {
        log.error("Indexed getter returns void - make it return the element type");
    }
    throw ex;
}

Prevention

When it happens

Trigger: An indexed getX(int) method declared void, registered as indexedReadMethod; usually a stub or a method named 'get' that performs a side effect rather than returning an element.

Common situations: Legacy get(int) methods that remove and return nothing; generated stubs; methods named 'get' used as commands.

Related errors


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