{"record":{"id":"7e4fa93eecdc2531","repo":"spring-projects/spring-framework","slug":"propertypath-is-required","errorCode":null,"errorMessage":"'propertyPath' is required","messagePattern":"'propertyPath' is required","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPathFactoryBean.java","lineNumber":187,"sourceCode":"\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\"Specify 'targetObject' or 'targetBeanName' in combination with 'propertyPath'\");\n\t\t\t}\n\n\t\t\t// No other properties specified: check bean name.\n\t\t\tint dotIndex;\n\t\t\tif (this.beanName == null || (dotIndex = this.beanName.indexOf('.')) <= 0) {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\"Neither 'targetObject' nor 'targetBeanName' specified, and PropertyPathFactoryBean \" +\n\t\t\t\t\t\t\"bean name '\" + this.beanName + \"' does not follow 'beanName.property' syntax\");\n\t\t\t}\n\t\t\ttargetBeanName = this.beanName.substring(0, dotIndex);\n\t\t\tthis.targetBeanName = targetBeanName;\n\t\t\tthis.propertyPath = this.beanName.substring(dotIndex + 1);\n\t\t}\n\n\t\telse if (this.propertyPath == null) {\n\t\t\t// either targetObject or targetBeanName specified\n\t\t\tthrow new IllegalArgumentException(\"'propertyPath' is required\");\n\t\t}\n\n\t\tif (this.targetBeanWrapper == null && StringUtils.hasLength(targetBeanName) &&\n\t\t\t\tthis.beanFactory.isSingleton(targetBeanName)) {\n\t\t\t// Eagerly fetch singleton target bean, and determine result type.\n\t\t\tObject bean = this.beanFactory.getBean(targetBeanName);\n\t\t\tthis.targetBeanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean);\n\t\t\tthis.resultType = this.targetBeanWrapper.getPropertyType(this.propertyPath);\n\t\t}\n\t}\n\n\n\t@Override\n\tpublic @Nullable Object getObject() throws BeansException {\n\t\tBeanWrapper target = this.targetBeanWrapper;\n\t\tif (target != null) {\n\t\t\tif (logger.isWarnEnabled() && this.targetBeanName != null &&\n\t\t\t\t\tthis.beanFactory instanceof ConfigurableBeanFactory cbf &&","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyPathFactoryBean.java#L169-L205","documentation":"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).","triggerScenarios":"XML with <property name=\"targetBeanName\" value=\"tb\"/> but no <property name=\"propertyPath\"/>. Programmatic setTargetBeanName(\"tb\") without setPropertyPath. Same for setTargetObject without a path.","commonSituations":"Setting the target then forgetting the path. Refactoring that dropped the propertyPath element while keeping the target.","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'."],"exampleFix":"// before (broken)\nPropertyPathFactoryBean fb = new PropertyPathFactoryBean();\nfb.setTargetBeanName(\"tb\");\n// after\nPropertyPathFactoryBean fb = new PropertyPathFactoryBean();\nfb.setTargetBeanName(\"tb\");\nfb.setPropertyPath(\"age\");","handlingStrategy":"validation","validationCode":"if ((targetObject != null || targetBeanName != null) && propertyPath == null) {\n    throw new IllegalStateException(\"propertyPath is required when a target is set\");\n}","typeGuard":"static boolean targetHasPath(Object targetObject, String targetBeanName, String propertyPath) {\n    boolean hasTarget = targetObject != null || targetBeanName != null;\n    return !hasTarget || propertyPath != null;\n}","tryCatchPattern":"try {\n    fb.setBeanFactory(beanFactory);\n} catch (IllegalArgumentException ex) {\n    if (ex.getMessage().contains(\"'propertyPath' is required\")) {\n        fb.setPropertyPath(\"age\");\n    }\n    throw ex;\n}","preventionTips":["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."],"tags":["spring","factory-bean","property-path","configuration","missing-property"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}