spring-projects/spring-framework · error · IllegalArgumentException
Write method must have exactly 1 or 2 parameters: ${method}
Error message
Write method must have exactly 1 or 2 parameters: ${method} What it means
IllegalArgumentException thrown by ExtendedBeanInfo when it encounters a method named like a setter (setX) whose parameter count is neither 1 (simple property) nor 2 (indexed property). ExtendedBeanInfo is the lenient BeanInfo implementation Spring uses when the class fails standard java.beans.Introspector rules; a setter with 0 or 3+ params violates even that leniency.
Source
Thrown at spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java:184
existingPd.setWriteMethod(method);
}
}
else if (nParams == 2) {
if (existingPd == null) {
this.propertyDescriptors.add(
new SimpleIndexedPropertyDescriptor(propertyName, null, null, null, method));
}
else if (existingPd instanceof IndexedPropertyDescriptor indexedPd) {
indexedPd.setIndexedWriteMethod(method);
}
else {
this.propertyDescriptors.remove(existingPd);
this.propertyDescriptors.add(new SimpleIndexedPropertyDescriptor(
propertyName, existingPd.getReadMethod(), existingPd.getWriteMethod(), null, method));
}
}
else {
throw new IllegalArgumentException("Write method must have exactly 1 or 2 parameters: " + method);
}
}
private @Nullable PropertyDescriptor findExistingPropertyDescriptor(String propertyName, Class<?> propertyType) {
for (PropertyDescriptor pd : this.propertyDescriptors) {
final Class<?> candidateType;
final String candidateName = pd.getName();
if (pd instanceof IndexedPropertyDescriptor indexedPd) {
candidateType = indexedPd.getIndexedPropertyType();
if (candidateName.equals(propertyName) &&
(candidateType.equals(propertyType) || candidateType.equals(propertyType.componentType()))) {
return pd;
}
}
else {
candidateType = pd.getPropertyType();
if (candidateName.equals(propertyName) &&
(candidateType.equals(propertyType) || propertyType.equals(candidateType.componentType()))) {View on GitHub (pinned to e8729d0438)
Solutions
- Rename the method so it does not look like a setter (does not start with 'set').
- If it must keep the name, give it exactly 1 (simple) or 2 (int-indexed) parameters.
- Force standard IntrospectionResults by avoiding the ExtendedBeanInfoFactory SPI registration if the class is incompatible.
- Exclude the method from introspection by making it non-public if it is internal.
Example fix
// before
public void setStatus(String code, String reason, long ts) { ... } // 3-arg 'setter'
// after
public void recordStatus(String code, String reason, long ts) { ... } Defensive patterns
Strategy: validation
Validate before calling
// Scan candidate setter methods before introspection
for (Method m : MyClass.class.getMethods()) {
if (m.getName().startsWith("set") && m.getName().length() > 3) {
int n = m.getParameterCount();
if (n != 1 && n != 2) {
throw new IllegalStateException("Suspicious setter arity: " + m);
}
}
} Type guard
static boolean hasOnlyValidSetterArities(Class<?> c) {
for (Method m : c.getMethods()) {
if (m.getName().startsWith("set") && m.getName().length() > 3) {
int n = m.getParameterCount();
if (n != 1 && n != 2) return false;
}
}
return true;
} Try / catch
try {
return new ExtendedBeanInfo(clazz).getPropertyDescriptors();
} catch (IllegalArgumentException ex) {
if (ex.getMessage().startsWith("Write method must have exactly 1 or 2 parameters")) {
// log the offending method and fall back to standard Introspector
return java.beans.Introspector.getBeanInfo(clazz).getPropertyDescriptors();
}
throw ex;
} Prevention
- Do not name non-setter methods with the 'set' prefix unless they take 1 or 2 args.
- Use record() or fluent accessors (loadX/applyX) for command-like methods.
- Add a static analysis rule flagging 'set'-prefixed methods with invalid arity.
When it happens
Trigger: Spring selecting ExtendedBeanInfo as the introspector (via ExtendedBeanInfoFactory) for a class whose setX method was given an unusual arity, e.g. setFoo() with no args, setFoo(a,b,c), or an overloaded setFoo(int, String, boolean).
Common situations: A method named setX for a reason other than property setting (e.g. configuration helper); overloaded setter that breaks JavaBean conventions; reflective code-generators producing method names beginning with 'set' that aren't actually setters.
Related errors
- Bad write method arg count: ${writeMethod}
- Bean property '{propertyName}' is not readable or has an inv
- No property '${propertyName}' found
- Failed to obtain BeanInfo for class [${beanClass.getName()}]
- Failed to re-introspect class [${beanClass.getName()}]
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/cd4f895361294696.json.
Report an issue: GitHub.