spring-projects/spring-framework · error · IllegalArgumentException
'propertyPath' is required
Error message
'propertyPath' is required
What it means
Thrown by PropertyPathFactoryBean.setBeanFactory() when a target (targetObject or targetBeanName) has been configured but propertyPath was not. After binding a target, Spring needs the path to evaluate; the bean-name shorthand cannot apply because a target is already present (the shorthand only kicks in when nothing is set).
Solutions
- Add <property name="propertyPath" value="age"/> (or setPropertyPath("age")) alongside the target.
- Use a nested path if needed, e.g. value="spouse.age".
- If you intended the shorthand, remove the targetBeanName/targetObject and rename the bean to 'tb.age'.
Example fix
// before (broken)
PropertyPathFactoryBean fb = new PropertyPathFactoryBean();
fb.setTargetBeanName("tb");
// after
PropertyPathFactoryBean fb = new PropertyPathFactoryBean();
fb.setTargetBeanName("tb");
fb.setPropertyPath("age"); Defensive patterns
Strategy: validation
Validate before calling
if ((targetObject != null || targetBeanName != null) && propertyPath == null) {
throw new IllegalStateException("propertyPath is required when a target is set");
} Type guard
static boolean targetHasPath(Object targetObject, String targetBeanName, String propertyPath) {
boolean hasTarget = targetObject != null || targetBeanName != null;
return !hasTarget || propertyPath != null;
} Try / catch
try {
fb.setBeanFactory(beanFactory);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("'propertyPath' is required")) {
fb.setPropertyPath("age");
}
throw ex;
} Prevention
- Always set propertyPath right after the target in code.
- In XML, keep <property name="propertyPath"/> adjacent to the target property.
- Cover the bean in a context-load smoke test.
When it happens
Trigger: XML with <property name="targetBeanName" value="tb"/> but no <property name="propertyPath"/>. Programmatic setTargetBeanName("tb") without setPropertyPath. Same for setTargetObject without a path.
Common situations: Setting the target then forgetting the path. Refactoring that dropped the propertyPath element while keeping the target.
Related errors
- Specify 'targetObject' or 'targetBeanName' in combination…
- Neither 'targetObject' nor 'targetBeanName' specified, and…
- Property 'serviceLocatorInterface' is required
- 'sourceList' is required
- 'sourceMap' is required
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/7e4fa93eecdc2531.
Report an issue: GitHub.
Appendix: source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPathFactoryBean.java:187
throw new IllegalArgumentException(
"Specify 'targetObject' or 'targetBeanName' in combination with 'propertyPath'");
}
// No other properties specified: check bean name.
int dotIndex;
if (this.beanName == null || (dotIndex = this.beanName.indexOf('.')) <= 0) {
throw new IllegalArgumentException(
"Neither 'targetObject' nor 'targetBeanName' specified, and PropertyPathFactoryBean " +
"bean name '" + this.beanName + "' does not follow 'beanName.property' syntax");
}
targetBeanName = this.beanName.substring(0, dotIndex);
this.targetBeanName = targetBeanName;
this.propertyPath = this.beanName.substring(dotIndex + 1);
}
else if (this.propertyPath == null) {
// either targetObject or targetBeanName specified
throw new IllegalArgumentException("'propertyPath' is required");
}
if (this.targetBeanWrapper == null && StringUtils.hasLength(targetBeanName) &&
this.beanFactory.isSingleton(targetBeanName)) {
// Eagerly fetch singleton target bean, and determine result type.
Object bean = this.beanFactory.getBean(targetBeanName);
this.targetBeanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean);
this.resultType = this.targetBeanWrapper.getPropertyType(this.propertyPath);
}
}
@Override
public @Nullable Object getObject() throws BeansException {
BeanWrapper target = this.targetBeanWrapper;
if (target != null) {
if (logger.isWarnEnabled() && this.targetBeanName != null &&
this.beanFactory instanceof ConfigurableBeanFactory cbf &&View on GitHub (pinned to 69bf83ad71)