{"record":{"id":"0731f98f62765991","repo":"theonedev/onedev","slug":"invalid-property-path-path","errorCode":null,"errorMessage":"Invalid property path: {path}.","messagePattern":"Invalid property path: (.+?)\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java","lineNumber":1217,"sourceCode":"\t * \t\tthe given property path.\n\t */\n\tprivate <V> BeanValueContext<?, V> getValueContextForPropertyValidation(BaseBeanValidationContext<?> validationContext, PathImpl propertyPath) {\n\t\tClass<?> clazz = validationContext.getRootBeanClass();\n\t\tBeanMetaData<?> beanMetaData = validationContext.getRootBeanMetaData();\n\t\tObject value = validationContext.getRootBean();\n\t\tPropertyMetaData propertyMetaData = null;\n\n\t\tIterator<Path.Node> propertyPathIter = propertyPath.iterator();\n\n\t\twhile ( propertyPathIter.hasNext() ) {\n\t\t\t// cast is ok, since we are dealing with engine internal classes\n\t\t\tNodeImpl propertyPathNode = (NodeImpl) propertyPathIter.next();\n\t\t\tpropertyMetaData = getBeanPropertyMetaData( beanMetaData, propertyPathNode );\n\n\t\t\t// if the property is not the leaf property, we set up the context for the next iteration\n\t\t\tif ( propertyPathIter.hasNext() ) {\n\t\t\t\tif ( !propertyMetaData.isCascading() ) {\n\t\t\t\t\tthrow LOG.getInvalidPropertyPathException( validationContext.getRootBeanClass(), propertyPath.asString() );\n\t\t\t\t}\n\n\t\t\t\tvalue = getCascadableValue( validationContext, value, propertyMetaData.getCascadables().iterator().next() );\n\t\t\t\tif ( value == null ) {\n\t\t\t\t\tthrow LOG.getUnableToReachPropertyToValidateException( validationContext.getRootBean(), propertyPath );\n\t\t\t\t}\n\t\t\t\tclazz = value.getClass();\n\n\t\t\t\t// if we are in the case of an iterable and we want to validate an element of this iterable, we have to get the\n\t\t\t\t// element value\n\t\t\t\tif ( propertyPathNode.isIterable() ) {\n\t\t\t\t\tpropertyPathNode = (NodeImpl) propertyPathIter.next();\n\n\t\t\t\t\tif ( propertyPathNode.getIndex() != null ) {\n\t\t\t\t\t\tvalue = ReflectionHelper.getIndexedValue( value, propertyPathNode.getIndex() );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( propertyPathNode.getKey() != null ) {\n\t\t\t\t\t\tvalue = ReflectionHelper.getMappedValue( value, propertyPathNode.getKey() );","sourceCodeStart":1199,"sourceCodeEnd":1235,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java#L1199-L1235","documentation":"Thrown by validateProperty/validateValue when the given PropertyPath references an intermediate (non-leaf) property that is not cascading (@Valid), so validation cannot traverse through it. Only the final path segment may be a non-cascading property; every earlier segment must be @Valid to descend into it.","triggerScenarios":"Calling validator.validateProperty(bean, \"address.street\") where the intermediate 'address' property lacks @Valid, or the path contains a typo so the resolved property has no cascading metadata.","commonSituations":"Deep property paths in programmatic validation, renamed/removed intermediate properties after refactoring, assuming nested traversal happens without @Valid on the container property.","solutions":["Annotate the intermediate property with @Valid so the path can cascade through it.","Shorten the path to only reference cascading properties, or validate the nested object separately.","Check the path string for typos against actual property names."],"exampleFix":"// before\nclass Order { Address address; } // no @Valid\nvalidator.validateProperty(order, \"address.street\");\n\n// after\nclass Order { @Valid Address address; }\nvalidator.validateProperty(order, \"address.street\");","handlingStrategy":"validation","validationCode":"// every segment except the last must be cascading\nboolean pathTraversable(Class<?> root, String path) {\n    String[] segs = path.split(\"\\\\.\");\n    Class<?> cur = root;\n    for (int i = 0; i < segs.length - 1; i++) {\n        try {\n            Field f = cur.getDeclaredField(segs[i]);\n            if (!f.isAnnotationPresent(Valid.class)) return false;\n            cur = f.getType();\n        } catch (NoSuchFieldException e) { return false; }\n    }\n    return true;\n}","typeGuard":"null","tryCatchPattern":"try {\n    validator.validateProperty(bean, path);\n} catch (ValidationException e) {\n    if (e.getMessage().startsWith(\"Invalid property path\")) {\n        // add @Valid to intermediate property or shorten the path\n    } else throw e;\n}","preventionTips":["Annotate @Valid on every property you navigate through in multi-segment paths.","Verify path strings against actual getter/field names before calling validateProperty.","Validate the nested object directly instead of deep paths when unsure."],"tags":["validation","property-path","bean-validation"],"backgroundTag":"invalid-property-path","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}