spring-projects/spring-framework · error · IllegalArgumentException

Neither 'targetObject' nor 'targetBeanName' specified, and…

Error message

Neither 'targetObject' nor 'targetBeanName' specified, and PropertyPathFactoryBean bean name '${beanName}' does not follow 'beanName.property' syntax

What it means

Thrown by PropertyPathFactoryBean.setBeanFactory() when none of targetObject, targetBeanName, or propertyPath are set, and the factory bean's own bean name does not contain a dot in the 'beanName.property' position. PropertyPathFactoryBean can infer target+path from the bean id (e.g. id 'tb.age'), but only if the id has a dot after position 0; otherwise it has nothing to work with.

Solutions

  1. Rename the bean to follow 'beanName.property', e.g. id="tb.age", and add no other properties.
  2. Or explicitly set targetBeanName and propertyPath on the bean and keep any id you like.
  3. Or set targetObject (inner bean) and propertyPath.

Example fix

<!-- before (broken): id has no dot, no props -->
<bean id="myValue" class="...PropertyPathFactoryBean"/>
<!-- after (shorthand) -->
<bean id="tb.age" class="...PropertyPathFactoryBean"/>
Defensive patterns

Strategy: validation

Validate before calling

String name = "tb"; // intended bean id
if (targetObject == null && targetBeanName == null && propertyPath == null) {
    if (name == null || name.indexOf('.') <= 0) {
        throw new IllegalStateException("bean id must be 'beanName.property' when nothing else is set");
    }
}

Type guard

static boolean beanNameHasPropertyDot(String beanName) {
    return beanName != null && beanName.indexOf('.') > 0;
}

Try / catch

try {
    fb.setBeanFactory(beanFactory);
} catch (IllegalArgumentException ex) {
    if (ex.getMessage().contains("does not follow 'beanName.property' syntax")) {
        // rename the bean or set target+propertyPath explicitly
    }
    throw ex;
}

Prevention

When it happens

Trigger: A PropertyPathFactoryBean bean with id 'myBean' (no dot) and no properties set. Bean name starting with a dot like '.age' (dotIndex == 0 is rejected). Bean name null (e.g. anonymous/inner registration edge cases).

Common situations: Intending the shorthand but giving the bean a plain id without a dot. Forgetting to set targetBeanName/propertyPath AND not naming the bean 'targetBean.property'. XML bean with an id but no inner properties.

Related errors


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

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPathFactoryBean.java:176

	@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");
		}

		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);

View on GitHub (pinned to 69bf83ad71)