spring-projects/spring-framework · error · NotReadablePropertyException
Bean property '{propertyName}' is not readable or has an inv
Error message
Bean property '{propertyName}' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? What it means
The default message of NotReadablePropertyException, raised in getPropertyValue(PropertyTokenHolder) when getLocalPropertyHandler(actualName) returns null or reports !ph.isReadable(). The hint about getter/setter type mismatch refers to BeanWrapperIntrospection: a setter whose parameter type does not match the getter return type can cause the property to be treated as non-readable. So the property either does not exist or its accessor pair is inconsistent.
Source
Thrown at spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java:603
throws TypeMismatchException {
return convertIfNecessary(propertyName, oldValue, newValue, td.getType(), td);
}
@Override
public @Nullable Object getPropertyValue(String propertyName) throws BeansException {
AbstractNestablePropertyAccessor nestedPa = getPropertyAccessorForPropertyPath(propertyName);
PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
return nestedPa.getPropertyValue(tokens);
}
@SuppressWarnings({"rawtypes", "unchecked"})
protected @Nullable Object getPropertyValue(PropertyTokenHolder tokens) throws BeansException {
String propertyName = tokens.canonicalName;
String actualName = tokens.actualName;
PropertyHandler ph = getLocalPropertyHandler(actualName);
if (ph == null || !ph.isReadable()) {
throw new NotReadablePropertyException(getRootClass(), this.nestedPath + propertyName);
}
try {
Object value = ph.getValue();
if (tokens.keys != null) {
if (value == null) {
if (isAutoGrowNestedPaths()) {
value = setDefaultValue(new PropertyTokenHolder(tokens.actualName));
}
else {
throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
"Cannot access indexed value of property referenced in indexed " +
"property path '" + propertyName + "': returned null");
}
}
StringBuilder indexedPropertyName = new StringBuilder(tokens.actualName);
// apply indexes and map keys
for (int i = 0; i < tokens.keys.length; i++) {
String key = tokens.keys[i];View on GitHub (pinned to e8729d0438)
Solutions
- Confirm a public getter exists for the property and that its name matches JavaBean conventions.
- Align the setter parameter type with the getter return type so the introspector treats the pair as consistent.
- Use wrapper.isReadableProperty(name) before calling getPropertyValue to avoid the exception.
- Correct the property name / check for typos.
Example fix
// before
public class Person { private String name; public void setName(String n) { this.name = n; } }
wrapper.getPropertyValue("name"); // no getter
// after
public String getName() { return name; } Defensive patterns
Strategy: validation
Validate before calling
if (wrapper.isReadableProperty(propertyName)) {
Object v = wrapper.getPropertyValue(propertyName);
} Type guard
static boolean hasConsistentGetterSetter(Class<?> bean, String name) {
try {
java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
for (java.beans.PropertyDescriptor pd : info.getPropertyDescriptors()) {
if (pd.getName().equals(name)) {
return pd.getReadMethod() != null
&& (pd.getWriteMethod() == null
|| pd.getWriteMethod().getParameterTypes()[0] == pd.getReadMethod().getReturnType());
}
}
return false;
} catch (Exception ex) { return false; }
} Try / catch
try { Object v = wrapper.getPropertyValue(propertyName); }
catch (NotReadablePropertyException ex) { /* property has no usable getter */ } Prevention
- Always provide a public getter matching JavaBean conventions.
- Keep setter parameter type == getter return type.
- Call isReadableProperty before reading unfamiliar names.
When it happens
Trigger: wrapper.getPropertyValue("foo") on a bean with no getFoo(); a bean where getFoo() returns String but setFoo(int) makes the pair inconsistent; accessing a write-only property for reading.
Common situations: Reading a property that only has a setter; model refactor renaming getters; binding/validation code that probes arbitrary property names; Kotlin data classes where a property is declared private.
Related errors
- Cannot access indexed value in property referenced in indexe
- Getter for property '${actualName}' threw exception
- Illegal attempt to get property '${actualName}' threw except
- Bad read method arg count: ${readMethod}
- Read method returns void: ${readMethod}
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/ce65561be06f0d41.json.
Report an issue: GitHub.