{"record":{"id":"86360db475577e7a","repo":"theonedev/onedev","slug":"no-value-extractor-found-for-type-type","errorCode":null,"errorMessage":"No value extractor found for type {type}.","messagePattern":"No value extractor found for type (.+?)\\.","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java","lineNumber":706,"sourceCode":"\t\tvalidateInContext( validationContext, cascadedValueContext, validationOrder );\n\t}\n\n\tprivate void validateCascadedContainerElementsForCurrentGroup(Object value, BaseBeanValidationContext<?> validationContext, ValueContext<?, ?> valueContext,\n\t\t\tList<ContainerCascadingMetaData> containerElementTypesCascadingMetaData) {\n\t\tfor ( ContainerCascadingMetaData cascadingMetaData : containerElementTypesCascadingMetaData ) {\n\t\t\tif ( !cascadingMetaData.isMarkedForCascadingOnAnnotatedObjectOrContainerElements() ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tValueExtractorDescriptor extractor = valueExtractorManager.getMaximallySpecificAndRuntimeContainerElementCompliantValueExtractor(\n\t\t\t\t\tcascadingMetaData.getEnclosingType(),\n\t\t\t\t\tcascadingMetaData.getTypeParameter(),\n\t\t\t\t\tvalue.getClass(),\n\t\t\t\t\tcascadingMetaData.getValueExtractorCandidates()\n\t\t\t);\n\n\t\t\tif ( extractor == null ) {\n\t\t\t\tthrow LOG.getNoValueExtractorFoundForTypeException( cascadingMetaData.getEnclosingType(), cascadingMetaData.getTypeParameter(), value.getClass() );\n\t\t\t}\n\n\t\t\tCascadingValueReceiver receiver = new CascadingValueReceiver( validationContext, valueContext, cascadingMetaData );\n\t\t\tValueExtractorHelper.extractValues( extractor, value, receiver );\n\t\t}\n\t}\n\n\tprivate class CascadingValueReceiver implements ValueExtractor.ValueReceiver {\n\n\t\tprivate final BaseBeanValidationContext<?> validationContext;\n\t\tprivate final ValueContext<?, ?> valueContext;\n\t\tprivate final ContainerCascadingMetaData cascadingMetaData;\n\n\t\tpublic CascadingValueReceiver(BaseBeanValidationContext<?> validationContext, ValueContext<?, ?> valueContext, ContainerCascadingMetaData cascadingMetaData) {\n\t\t\tthis.validationContext = validationContext;\n\t\t\tthis.valueContext = valueContext;\n\t\t\tthis.cascadingMetaData = cascadingMetaData;\n\t\t}","sourceCodeStart":688,"sourceCodeEnd":724,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java#L688-L724","documentation":"Hibernate Validator throws this when cascaded validation (@Valid) reaches a container-typed value (Optional, List, Map, custom generic) but no ValueExtractor is registered that knows how to unwrap that type parameter. The framework cannot descend into the container, so it fails fast instead of silently skipping element validation.","triggerScenarios":"Validating a bean with @Valid on a field/parameter whose declared type is a generic container (Optional<T>, List<T>, Map<K,V>, or a custom container) for which no matching ValueExtractor exists in the registered ValueExtractorRepository — typically a custom container type without a @ExtractValue annotated method or a registered extractor.","commonSituations":"Upgrading Hibernate Validator (extractor discovery rules changed between 6.x versions), using Optional/Collection wrappers from third-party libraries, or defining custom generic wrapper types (e.g. a Page<T> or Result<T> class) annotated with @Valid without registering an extractor.","solutions":["Add an @ExtractValue-annotated method (or field) to the custom container type so the framework knows which type parameter holds the validated values.","Register a custom ValueExtractor for the container type via META-INF/services/javax.validation.valueextraction.ValueExtractor or ConstraintValidatorFactory/parameterized extractor registration.","Remove @Valid from the field if element validation is not intended.","Check that the same Hibernate Validator version is on the classpath at runtime as at compile time (mixed versions break extractor resolution)."],"exampleFix":"// before\nclass Result<T> { T value; }\n@Valid Result<@NotNull String> result; // throws at validate()\n\n// after\nclass Result<T> {\n    T value;\n    @ExtractValue\n    public T getValue() { return value; }\n}\n@Valid Result<@NotNull String> result;","handlingStrategy":"validation","validationCode":"// before validate(), ensure the container type has an extractor\nboolean hasExtractor(Class<?> containerType, ValueExtractorRepository repo) {\n    return repo.getValueExtractorCandidates(containerType, TypeUseKind.CONTAINER_ELEMENT)\n               .size() > 0;\n}","typeGuard":"static <T> boolean isSupportedContainer(Object v) {\n    return v instanceof Collection || v instanceof Map || v instanceof Optional\n        || v.getClass().isAnnotationPresent(ExtractValue.class)\n        || java.util.Arrays.stream(v.getClass().getDeclaredMethods())\n            .anyMatch(m -> m.isAnnotationPresent(ExtractValue.class));\n}","tryCatchPattern":"try {\n    validator.validate(bean);\n} catch (ValidationException e) {\n    if (e.getMessage().contains(\"No value extractor found\")) {\n        // register extractor or drop @Valid on that field, then retry\n    } else throw e;\n}","preventionTips":["Annotate a value-returning method with @ExtractValue on every custom container type used with @Valid.","Prefer JDK/standard containers (List, Map, Optional) which have built-in extractors.","Keep Hibernate Validator versions consistent across the classpath."],"tags":["validation","bean-validation","value-extractor","generics"],"backgroundTag":"unsupported-operation","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"}