spring-projects/spring-framework · error · IllegalArgumentException
Specify 'targetObject' or 'targetBeanName' in combination…
Error message
Specify 'targetObject' or 'targetBeanName' in combination with 'propertyPath'
What it means
Thrown by PropertyPathFactoryBean.setBeanFactory() when a propertyPath has been supplied but neither targetObject nor targetBeanName was set. The property path needs a target to be evaluated against; without a target Spring cannot infer one (unlike the bean-name shorthand, propertyPath alone does not carry the bean name).
Solutions
- Add targetBeanName (e.g. <property name="targetBeanName" value="tb"/>) alongside propertyPath.
- Or add targetObject (an inner bean or ref) alongside propertyPath.
- If you wanted the bean-name shorthand, remove the propertyPath property and rely on the bean id 'tb.age'.
Example fix
<!-- before (broken) --> <bean id="x" class="...PropertyPathFactoryBean"> <property name="propertyPath" value="age"/> </bean> <!-- after --> <bean id="x" class="...PropertyPathFactoryBean"> <property name="targetBeanName" value="tb"/> <property name="propertyPath" value="age"/> </bean>
Defensive patterns
Strategy: validation
Validate before calling
if (propertyPath != null && targetObject == null && targetBeanName == null) {
throw new IllegalStateException("propertyPath requires a targetObject or targetBeanName");
} Type guard
static boolean pathHasTarget(String propertyPath, String targetBeanName, Object targetObject) {
return propertyPath == null || targetObject != null || targetBeanName != null;
} Try / catch
try {
fb.setBeanFactory(beanFactory);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().contains("in combination with 'propertyPath'")) {
// add targetBeanName or targetObject, then retry
}
throw ex;
} Prevention
- When using propertyPath explicitly, always pair it with targetBeanName or targetObject.
- If you want the bean-name shorthand, set ONLY the bean id and nothing else.
- Document the three valid PropertyPathFactoryBean configuration forms for your team.
When it happens
Trigger: XML with only <property name="propertyPath" value="age"/> and no target. Programmatic setPropertyPath("age") without setTargetObject/setTargetBeanName. Intent to use the bean-name shorthand but accidentally also setting propertyPath.
Common situations: Misunderstanding that the 'beanName.property' shorthand works only when NOTHING else is set; adding propertyPath disables the shorthand. Partial migration between the two forms.
Related errors
- 'propertyPath' is required
- 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/fffe9793083bec82.
Report an issue: GitHub.
Appendix: source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPathFactoryBean.java:169
*/
@Override
public void setBeanName(String beanName) {
this.beanName = StringUtils.trimAllWhitespace(BeanFactoryUtils.originalBeanName(beanName));
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
String targetBeanName = this.targetBeanName;
if (this.targetBeanWrapper != null && targetBeanName != null) {
throw new IllegalArgumentException("Specify either 'targetObject' or 'targetBeanName', not both");
}
if (this.targetBeanWrapper == null && targetBeanName == null) {
if (this.propertyPath != null) {
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");View on GitHub (pinned to 69bf83ad71)