spring-projects/spring-framework · error · IntrospectionException

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

Error message

Type mismatch between read and write methods: {readMethod} - {writeMethod}

What it means

Thrown as java.beans.IntrospectionException by PropertyDescriptorUtils.findPropertyType when both a read method and a write method are supplied and their property types are mutually non-assignable. The getter return type and setter parameter type must be in an assignable relationship for the property to have a single coherent type.

Source

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

				throw new IntrospectionException("Read method returns void: " + readMethod);
			}
		}

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

		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;

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Align the getter return type and setter parameter type (make one assignable to the other, ideally identical).
  2. Remove the conflicting overload or rename one of the accessors.
  3. Regenerate the class with consistent accessor types.

Example fix

// before
public Number getValue() { ... }
public void setValue(String v) { ... }

// after
public String getValue() { ... }
public void setValue(String v) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// before declaring the property consistent
Class<?> readType = readMethod.getReturnType();
Class<?> writeType = writeMethod.getParameterTypes()[0];
if (!readType.isAssignableFrom(writeType) && !writeType.isAssignableFrom(readType)) {
    throw new IllegalStateException("read/write type clash: " + readType + " vs " + writeType);
}

Type guard

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

Prevention

When it happens

Trigger: findPropertyType(readMethod, writeMethod) computes propertyType from the getter, then checks writeMethod.getParameterTypes()[0]; if neither propertyType.isAssignableFrom(param[0]) nor param[0].isAssignableFrom(propertyType), it throws.

Common situations: A getter returns Number but the setter takes String (or vice versa), overloading that creates an inconsistent read/write pair, refactoring a field's type without updating both accessors, or Lombok @Delegate / generated code producing mismatched pairs.

Related errors


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