spring-projects/spring-framework · error · IntrospectionException

Non int index to indexed read method: ${indexedReadMethod}

Error message

Non int index to indexed read method: ${indexedReadMethod}

What it means

IntrospectionException from PropertyDescriptorUtils.findIndexedPropertyType when the single parameter of an indexed read method is not int. The JavaBean spec mandates that indexed accessors use int as the index type; long, Integer, or any other type is rejected.

Source

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

		return propertyType;
	}

	/**
	 * 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

View on GitHub (pinned to e8729d0438)

Solutions

  1. Change the indexed getter's index parameter type to primitive int.
  2. If you need long indexing, do not use IndexedPropertyDescriptor - expose a custom accessor pattern instead.
  3. Regenerate any code-producing non-int indices.

Example fix

// before
public String getItems(long index) { ... }

// after
public String getItems(int index) { ... }
Defensive patterns

Strategy: type-guard

Validate before calling

static void assertIntIndex(Method indexedReadMethod) {
    if (indexedReadMethod.getParameterTypes()[0] != int.class) {
        throw new IllegalArgumentException("Indexed read index must be int: " + indexedReadMethod);
    }
}

Type guard

static boolean hasIntIndex(Method m) {
    Class<?>[] p = m.getParameterTypes();
    return p.length == 1 && p[0] == int.class;
}

Try / catch

try {
    return new IndexedPropertyDescriptor(name, null, null, indexedReadMethod, indexedWriteMethod);
} catch (java.beans.IntrospectionException ex) {
    if (ex.getMessage().startsWith("Non int index to indexed read")) {
        log.error("Change {} index param to int", indexedReadMethod);
    }
    throw ex;
}

Prevention

When it happens

Trigger: An indexed getter declared as getX(long index) or getX(Integer index) being registered as an indexed read method; passing a boxed Integer or non-int primitive as the index parameter.

Common situations: Code using long indices for large collections; auto-boxed Integer parameters from generated code; cross-language interop producing non-int index types.

Related errors


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