Skip to content

[Java][Spring] enhance useBeanValidation to generate @Valid for the returned objects too (resolve #25214) - #25215

Open
LeosBitto wants to merge 3 commits into
OpenAPITools:masterfrom
LeosBitto:useBeanValidationForResponses
Open

LeosBitto wants to merge 3 commits into
OpenAPITools:masterfrom
LeosBitto:useBeanValidationForResponses

Conversation

@LeosBitto

@LeosBitto LeosBitto commented Oct 11, 2026 •

Copy link
Copy Markdown

We use openapi-generator-maven-plugin to generate interfaces for the REST clients, which we then create using RestClient, HttpServiceProxyFactory and org.springframework.aop.framework.ProxyFactory. With useBeanValidation=true this causes validation of the method parameters (because they are annotated @Valid in the generated interface), but it does not validate the response (because it is not annotated @Valid in the generated interface).

This pull request adds @Valid to the responses, including the generic types (e.g. List<@Valid SomeType>). It intentionally does not add @Valid for the generic type of ResponseEntity (generated when useResponseEntity=true) to make sure that it does not become ResponseEntity<@Valid ResponseType>, because that would break applications which do not have any implementation of ValueExtractor<ResponseEntity<@ExtractedValue ?>>. The same applies for Mono and Flux as well.

The intentional choice is to generate @Valid ResponseEntity< ResponseType > because that enables validating ResponseType when the application provides a simple implementation of ValueExtractor<ResponseEntity<@ExtractedValue ?>> and does not break anything (keeps the backward compatibility) when the application does not provide such implementation of ValueExtractor.

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

CC Java Spring @cachescrubber @welshm @MelleD @atextor @manedev79 @javisst @borsch @banlevente @Zomzog @martin-mfg @KannaKim

I have created this pull request to resolve #25214


Summary by cubic

With useBeanValidation enabled, generated Spring API methods now annotate response values with @Valid, enabling validation of returned bodies as well as request parameters.

  • Applies to model responses and model elements in collections and maps, including reactive signatures, but leaves element types unannotated in reactive arrays.
  • Leaves primitive and void responses unannotated and avoids annotating ResponseEntity's generic type, which would require a ValueExtractor.

Written for commit ea3ba18. Summary will update on new commits.

View guided diff

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="modules/openapi-generator/src/main/resources/JavaSpring/responseType.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/JavaSpring/responseType.mustache:1">
P3: `@Valid ` is prefixed to every non-void return type when `useBeanValidation` is enabled, not just model returns. Operations returning `String`, `Integer`, `byte[]`, `File`, `List<String>`, or `Map<String, String>` will now generate `@Valid String ...` (and `@Valid Flux<...>`/`@Valid ResponseEntity<...>` for unannotated containers), even though the PR description states non-model elements are left unannotated. These annotations compile (javax/jakarta `Valid` has `TYPE_USE`) but are meaningless no-ops on every generated method and contradict the stated scope. Gate the prefix on the return being a model, e.g. restrict it to `{{#returnProperty.isModel}}` while keeping the element-level `@Valid` from `validatedReturnType.mustache` for generic containers.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/JavaSpring/validatedReturnType.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/JavaSpring/validatedReturnType.mustache:1">
P2: Nested collection responses skip cascade validation because this branch checks only the immediate item. Apply the model annotation recursively so a `List<List<Pet>>` response annotates its `Pet` elements.</violation>
</file>

<file name="modules/openapi-generator/src/main/resources/JavaSpring/returnTypes.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/JavaSpring/returnTypes.mustache:1">
P2: Map values are annotated even when the response is wrapped in `ResponseEntity`, producing `ResponseEntity<Map<String, @Valid Pet>>` and requiring the `ResponseEntity` value extractor the PR intends to avoid. Suppress map-value `@Valid` for `useResponseEntity` returns.</violation>
</file>

Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Reply to a comment to ask cubic a question or push back. It learns from your replies.

View guided diff | Re-trigger cubic

Comment thread modules/openapi-generator/src/main/resources/JavaSpring/responseType.mustache Outdated
@@ -0,0 +1 @@
{{#useBeanValidation}}{{#returnProperty.items.isModel}}{{#lambdaBeanValidationType}}{{{returnType}}}{{/lambdaBeanValidationType}}{{/returnProperty.items.isModel}}{{^returnProperty.items.isModel}}{{{returnType}}}{{/returnProperty.items.isModel}}{{/useBeanValidation}}{{^useBeanValidation}}{{{returnType}}}{{/useBeanValidation}} No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Nested collection responses skip cascade validation because this branch checks only the immediate item. Apply the model annotation recursively so a List<List<Pet>> response annotates its Pet elements.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/main/resources/JavaSpring/validatedReturnType.mustache, line 1:

<comment>Nested collection responses skip cascade validation because this branch checks only the immediate item. Apply the model annotation recursively so a `List<List<Pet>>` response annotates its `Pet` elements.</comment>

<file context>
@@ -0,0 +1 @@
+{{#useBeanValidation}}{{#returnProperty.items.isModel}}{{#lambdaBeanValidationType}}{{{returnType}}}{{/lambdaBeanValidationType}}{{/returnProperty.items.isModel}}{{^returnProperty.items.isModel}}{{{returnType}}}{{/returnProperty.items.isModel}}{{/useBeanValidation}}{{^useBeanValidation}}{{{returnType}}}{{/useBeanValidation}}
\ No newline at end of file
</file context>

@@ -1 +1 @@
{{#isMap}}Map<String, {{{returnType}}}>{{/isMap}}{{#isArray}}{{#reactive}}{{{returnType}}}{{/reactive}}{{^reactive}}{{#generateGenericResponseEntity}}?{{/generateGenericResponseEntity}}{{^generateGenericResponseEntity}}{{{returnContainer}}}<{{{returnType}}}>{{/generateGenericResponseEntity}}{{/reactive}}{{/isArray}}{{^returnContainer}}{{#useResponseEntity}}{{#generateGenericResponseEntity}}?{{/generateGenericResponseEntity}}{{^generateGenericResponseEntity}}{{{returnType}}}{{/generateGenericResponseEntity}}{{/useResponseEntity}}{{^useResponseEntity}}{{#isDelegate}}{{#isVoid}}{{#responseWrapper}}{{{returnType}}}{{/responseWrapper}}{{^responseWrapper}}void{{/responseWrapper}}{{/isVoid}}{{^isVoid}}{{{returnType}}}{{/isVoid}}{{/isDelegate}}{{^isDelegate}}{{#async}}{{{returnType}}}{{/async}}{{^async}}{{#isVoid}}{{#responseWrapper}}{{{returnType}}}{{/responseWrapper}}{{^responseWrapper}}void{{/responseWrapper}}{{/isVoid}}{{^isVoid}}{{{returnType}}}{{/isVoid}}{{/async}}{{/isDelegate}}{{/useResponseEntity}}{{/returnContainer}} No newline at end of file
{{#isMap}}Map<String, {{>validatedReturnType}}>{{/isMap}}{{#isArray}}{{#reactive}}{{{returnType}}}{{/reactive}}{{^reactive}}{{#generateGenericResponseEntity}}?{{/generateGenericResponseEntity}}{{^generateGenericResponseEntity}}{{{returnContainer}}}<{{>validatedReturnType}}>{{/generateGenericResponseEntity}}{{/reactive}}{{/isArray}}{{^returnContainer}}{{#useResponseEntity}}{{#generateGenericResponseEntity}}?{{/generateGenericResponseEntity}}{{^generateGenericResponseEntity}}{{{returnType}}}{{/generateGenericResponseEntity}}{{/useResponseEntity}}{{^useResponseEntity}}{{#isDelegate}}{{#isVoid}}{{#responseWrapper}}{{{returnType}}}{{/responseWrapper}}{{^responseWrapper}}void{{/responseWrapper}}{{/isVoid}}{{^isVoid}}{{{returnType}}}{{/isVoid}}{{/isDelegate}}{{^isDelegate}}{{#async}}{{{returnType}}}{{/async}}{{^async}}{{#isVoid}}{{#responseWrapper}}{{{returnType}}}{{/responseWrapper}}{{^responseWrapper}}void{{/responseWrapper}}{{/isVoid}}{{^isVoid}}{{{returnType}}}{{/isVoid}}{{/async}}{{/isDelegate}}{{/useResponseEntity}}{{/returnContainer}} No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Map values are annotated even when the response is wrapped in ResponseEntity, producing ResponseEntity<Map<String, @Valid Pet>> and requiring the ResponseEntity value extractor the PR intends to avoid. Suppress map-value @Valid for useResponseEntity returns.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/main/resources/JavaSpring/returnTypes.mustache, line 1:

<comment>Map values are annotated even when the response is wrapped in `ResponseEntity`, producing `ResponseEntity<Map<String, @Valid Pet>>` and requiring the `ResponseEntity` value extractor the PR intends to avoid. Suppress map-value `@Valid` for `useResponseEntity` returns.</comment>

<file context>
@@ -1 +1 @@
-{{#isMap}}Map<String, {{{returnType}}}>{{/isMap}}{{#isArray}}{{#reactive}}{{{returnType}}}{{/reactive}}{{^reactive}}{{#generateGenericResponseEntity}}?{{/generateGenericResponseEntity}}{{^generateGenericResponseEntity}}{{{returnContainer}}}<{{{returnType}}}>{{/generateGenericResponseEntity}}{{/reactive}}{{/isArray}}{{^returnContainer}}{{#useResponseEntity}}{{#generateGenericResponseEntity}}?{{/generateGenericResponseEntity}}{{^generateGenericResponseEntity}}{{{returnType}}}{{/generateGenericResponseEntity}}{{/useResponseEntity}}{{^useResponseEntity}}{{#isDelegate}}{{#isVoid}}{{#responseWrapper}}{{{returnType}}}{{/responseWrapper}}{{^responseWrapper}}void{{/responseWrapper}}{{/isVoid}}{{^isVoid}}{{{returnType}}}{{/isVoid}}{{/isDelegate}}{{^isDelegate}}{{#async}}{{{returnType}}}{{/async}}{{^async}}{{#isVoid}}{{#responseWrapper}}{{{returnType}}}{{/responseWrapper}}{{^responseWrapper}}void{{/responseWrapper}}{{/isVoid}}{{^isVoid}}{{{returnType}}}{{/isVoid}}{{/async}}{{/isDelegate}}{{/useResponseEntity}}{{/returnContainer}}
\ No newline at end of file
+{{#isMap}}Map<String, {{>validatedReturnType}}>{{/isMap}}{{#isArray}}{{#reactive}}{{{returnType}}}{{/reactive}}{{^reactive}}{{#generateGenericResponseEntity}}?{{/generateGenericResponseEntity}}{{^generateGenericResponseEntity}}{{{returnContainer}}}<{{>validatedReturnType}}>{{/generateGenericResponseEntity}}{{/reactive}}{{/isArray}}{{^returnContainer}}{{#useResponseEntity}}{{#generateGenericResponseEntity}}?{{/generateGenericResponseEntity}}{{^generateGenericResponseEntity}}{{{returnType}}}{{/generateGenericResponseEntity}}{{/useResponseEntity}}{{^useResponseEntity}}{{#isDelegate}}{{#isVoid}}{{#responseWrapper}}{{{returnType}}}{{/responseWrapper}}{{^responseWrapper}}void{{/responseWrapper}}{{/isVoid}}{{^isVoid}}{{{returnType}}}{{/isVoid}}{{/isDelegate}}{{^isDelegate}}{{#async}}{{{returnType}}}{{/async}}{{^async}}{{#isVoid}}{{#responseWrapper}}{{{returnType}}}{{/responseWrapper}}{{^responseWrapper}}void{{/responseWrapper}}{{/isVoid}}{{^isVoid}}{{{returnType}}}{{/isVoid}}{{/async}}{{/isDelegate}}{{/useResponseEntity}}{{/returnContainer}}
\ No newline at end of file
</file context>

@@ -1 +1 @@
{{^vendorExtensions.x-sse}}{{#reactive}}{{#useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{{returnContainer}}}<{{>returnTypes}}>>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{#isArray}}Flux<{{/isArray}}{{>returnTypes}}{{#isArray}}>{{/isArray}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{^useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<{{{returnContainer}}}<{{>returnTypes}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{/reactive}}{{^reactive}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{#responseWrapper}}>{{/responseWrapper}}{{/reactive}}{{/vendorExtensions.x-sse}}{{#vendorExtensions.x-sse}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}{{{returnContainer}}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/vendorExtensions.x-sse}} No newline at end of file
{{#useBeanValidation}}{{^isVoid}}@Valid {{/isVoid}}{{/useBeanValidation}}{{^vendorExtensions.x-sse}}{{#reactive}}{{#useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{{returnContainer}}}<{{>returnTypes}}>>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{#isArray}}Flux<{{>validatedReturnType}}>{{/isArray}}{{^isArray}}{{>returnTypes}}{{/isArray}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{^useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<{{{returnContainer}}}<{{>returnTypes}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{#isArray}}{{>validatedReturnType}}{{/isArray}}{{^isArray}}{{>returnTypes}}{{/isArray}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{/reactive}}{{^reactive}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{#responseWrapper}}>{{/responseWrapper}}{{/reactive}}{{/vendorExtensions.x-sse}}{{#vendorExtensions.x-sse}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}{{{returnContainer}}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{#isArray}}{{>validatedReturnType}}{{/isArray}}{{^isArray}}{{>returnTypes}}{{/isArray}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/vendorExtensions.x-sse}} No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: @Valid is prefixed to every non-void return type when useBeanValidation is enabled, not just model returns. Operations returning String, Integer, byte[], File, List<String>, or Map<String, String> will now generate @Valid String ... (and @Valid Flux<...>/@Valid ResponseEntity<...> for unannotated containers), even though the PR description states non-model elements are left unannotated. These annotations compile (javax/jakarta Valid has TYPE_USE) but are meaningless no-ops on every generated method and contradict the stated scope. Gate the prefix on the return being a model, e.g. restrict it to {{#returnProperty.isModel}} while keeping the element-level @Valid from validatedReturnType.mustache for generic containers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/main/resources/JavaSpring/responseType.mustache, line 1:

<comment>`@Valid ` is prefixed to every non-void return type when `useBeanValidation` is enabled, not just model returns. Operations returning `String`, `Integer`, `byte[]`, `File`, `List<String>`, or `Map<String, String>` will now generate `@Valid String ...` (and `@Valid Flux<...>`/`@Valid ResponseEntity<...>` for unannotated containers), even though the PR description states non-model elements are left unannotated. These annotations compile (javax/jakarta `Valid` has `TYPE_USE`) but are meaningless no-ops on every generated method and contradict the stated scope. Gate the prefix on the return being a model, e.g. restrict it to `{{#returnProperty.isModel}}` while keeping the element-level `@Valid` from `validatedReturnType.mustache` for generic containers.</comment>

<file context>
@@ -1 +1 @@
-{{^vendorExtensions.x-sse}}{{#reactive}}{{#useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{{returnContainer}}}<{{>returnTypes}}>>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{#isArray}}Flux<{{/isArray}}{{>returnTypes}}{{#isArray}}>{{/isArray}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{^useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<{{{returnContainer}}}<{{>returnTypes}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{/reactive}}{{^reactive}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{#responseWrapper}}>{{/responseWrapper}}{{/reactive}}{{/vendorExtensions.x-sse}}{{#vendorExtensions.x-sse}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}{{{returnContainer}}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/vendorExtensions.x-sse}}
\ No newline at end of file
+{{#useBeanValidation}}{{^isVoid}}@Valid {{/isVoid}}{{/useBeanValidation}}{{^vendorExtensions.x-sse}}{{#reactive}}{{#useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{{returnContainer}}}<{{>returnTypes}}>>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{#isArray}}Flux<{{>validatedReturnType}}>{{/isArray}}{{^isArray}}{{>returnTypes}}{{/isArray}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{^useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<{{{returnContainer}}}<{{>returnTypes}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{#isArray}}{{>validatedReturnType}}{{/isArray}}{{^isArray}}{{>returnTypes}}{{/isArray}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{/reactive}}{{^reactive}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{#responseWrapper}}>{{/responseWrapper}}{{/reactive}}{{/vendorExtensions.x-sse}}{{#vendorExtensions.x-sse}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}{{{returnContainer}}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{#isArray}}{{>validatedReturnType}}{{/isArray}}{{^isArray}}{{>returnTypes}}{{/isArray}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/vendorExtensions.x-sse}}
\ No newline at end of file
</file context>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where exactly does the PR description state that non-model elements are left unannotated?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LeosBitto It doesn't — I misattributed that. Your description only excludes the generic type parameter of ResponseEntity (and Mono/Flux); for everything else it says @Valid is added to responses "including the generic types (e.g. List<@Valid SomeType>)", with no statement about non-model elements.

The "non-model elements stay bare" detail actually comes from the implementation, not the description: validatedReturnType.mustache only emits element-level @Valid when returnProperty.items.isModel, so List<Integer>/Map<String, String> items stay unannotated while List<@Valid Pet> doesn't. The closest textual source is the auto-summary's "Leaves primitive and void responses unannotated" — but that's cubic's summary, not your PR text.

So the "contradicts the stated scope" framing in my comment was wrong, and I'll drop it. The underlying observation is still factually true — the outer prefix lands on every non-void return, e.g. @Valid ResponseEntity<String> loginUser and @Valid ResponseEntity<Map<String, Integer>> getInventory in the samples — and your new test asserts that deliberately (annotation + name + " getName(" with name = String). If that uniformity is intended, the only remaining nit is that @Valid on a String/Integer/Map return is a validation no-op; it's harmless, and arguably aligned with the "validate all returned objects" goal.

Tip: get faster answers by chatting with cubic’s review copilot in the review UI

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have ammended the PR description with my deliberate choice to generate @Valid ResponseEntity< SomeType > and an explanation why I have made such choice. @cubic-dev-ai please reconsider all your comments in this PR with regards to this information.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LeosBitto I can help — what did you want me to do?

  • Manage learnings: reply in the relevant thread and say @cubic add this to our learnings (I'll extract the learning from context). For delete/update, paste the learning link from Settings → AI review → Learnings.
  • Make a code change: @cubic fix this and push commits (or open a PR)
  • Ask a question: @cubic why is this needed?

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 existing issues remain and 58 new issues found across 310 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="samples/client/petstore/spring-http-interface-springboot-4/src/main/java/org/openapitools/api/FakeApi.java">

<violation number="1" location="samples/client/petstore/spring-http-interface-springboot-4/src/main/java/org/openapitools/api/FakeApi.java:92">
P1: `@Valid` cascades into the `ResponseEntity`, not its generic body, so this does not validate the returned `OuterCompositeDto`. Handle the body with supported unwrapping; annotating the wrapper cannot validate the payload.</violation>
</file>

<file name="samples/server/petstore/springboot-include-http-request-context/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/server/petstore/springboot-include-http-request-context/src/main/java/org/openapitools/api/StoreApi.java:142">
P2: `@Valid` here cascades only into the `ResponseEntity` bean; it does not validate the `OrderDto` in its unannotated type argument. Use a supported cascade into the response body, or omit this ineffective annotation.</violation>
</file>

<file name="samples/client/petstore/spring-cloud-deprecated/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/client/petstore/spring-cloud-deprecated/src/main/java/org/openapitools/api/StoreApi.java:127">
P1: This annotation cascades validation into the `ResponseEntity` wrapper, not its `Order` body, so the returned model is never validated. Add a body-validation mechanism for `ResponseEntity` before emitting `@Valid` here.</violation>
</file>

<file name="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/UserApi.java">

<violation number="1" location="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/UserApi.java:188">
P1: This `@Valid` cascades on `ResponseEntity`, not its body; the unannotated `User` type argument means response model constraints are never checked. Add a supported body-cascade mechanism or omit this annotation.</violation>
</file>

<file name="samples/openapi3/client/petstore/spring-stubs-skip-default-interface/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/openapi3/client/petstore/spring-stubs-skip-default-interface/src/main/java/org/openapitools/api/PetApi.java:71">
P1: This cascades validation into the `ResponseEntity` wrapper, not its `Pet` body, so returned models are not validated. Cascade into the payload and provide a supported way to unwrap `ResponseEntity` during validation.</violation>
</file>

<file name="samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApi.java">

<violation number="1" location="samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApi.java:228">
P1: This does not validate the returned model: `@Valid` cascades on the `ResponseEntity`, not its generic body, so `ResponseObjectWithDifferentFieldNames` is never reached without a `ResponseEntity` value extractor. Add a supported body-cascading or explicit payload-validation mechanism.</violation>
</file>

<file name="samples/openapi3/client/petstore/spring-stubs-skip-default-interface/src/main/java/org/openapitools/api/UserApi.java">

<violation number="1" location="samples/openapi3/client/petstore/spring-stubs-skip-default-interface/src/main/java/org/openapitools/api/UserApi.java:189">
P2: This cascades validation into the `ResponseEntity`, not its `User` body, so the returned model is not validated. Add a supported cascade path to the body (for example, a `ValueExtractor` and `@Valid` on the type argument) or omit this ineffective annotation.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-3-include-http-request-context/src/main/java/org/openapitools/api/UserApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-3-include-http-request-context/src/main/java/org/openapitools/api/UserApi.java:205">
P2: This cascades validation on the `ResponseEntity`, not its `User` body, so returned users are never validated. Cascade to the body using a supported extraction strategy, or omit this ineffective annotation.</violation>
</file>

<file name="samples/server/petstore/springboot-builtin-validation/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/server/petstore/springboot-builtin-validation/src/main/java/org/openapitools/api/PetApi.java:149">
P1: These annotations do not validate the returned pets: `@Valid` cascades into the `ResponseEntity` bean, but reaching the nested `List<@Valid Pet>` requires extracting the `ResponseEntity` body. Provide supported unwrapping or omit the nested cascade for this wrapper.</violation>
</file>

<file name="samples/server/petstore/springboot-beanvalidation-no-nullable/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/server/petstore/springboot-beanvalidation-no-nullable/src/main/java/org/openapitools/api/PetApi.java:149">
P1: The nested cascade still has to unwrap `ResponseEntity` to reach `Pet`, but Bean Validation has no `ResponseEntity` value extractor; validating these return values can fail with a missing-extractor exception. Keep the response type argument unannotated or provide an extractor.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-3-include-http-request-context/src/main/java/org/openapitools/api/PetApiDelegate.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-3-include-http-request-context/src/main/java/org/openapitools/api/PetApiDelegate.java:85">
P1: This nested `@Valid Pet` requires Bean Validation to extract `ResponseEntity`'s type argument, but no `ResponseEntity` `ValueExtractor` is registered. Return-value validation therefore fails instead of validating list items; omit this nested cascade for `useResponseEntity` or provide an extractor.</violation>
</file>

<file name="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/UserApiDelegate.java">

<violation number="1" location="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/UserApiDelegate.java:92">
P2: This cascades into `ResponseEntity`, not its body, so the returned `User` is still not validated. Validate the body explicitly or register a `ResponseEntity` value extractor and put `@Valid` on the type argument.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-3/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-3/src/main/java/org/openapitools/api/PetApi.java:164">
P1: These signatures cascade into the `ResponseEntity` wrapper, not its body, so neither the returned `Pet` nor the annotated list elements are validated. Add a `ResponseEntity` value extractor and put `@Valid` on its type argument, or validate the response body explicitly.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/StoreApi.java:140">
P1: This cascades validation onto the `ResponseEntity`, not its generic body, so returned models and map elements remain unvalidated. Validate the unwrapped response body or omit this annotation for `ResponseEntity` signatures unless a suitable value extractor is provided.</violation>
</file>

<file name="samples/server/petstore/springboot-lombok-data/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/server/petstore/springboot-lombok-data/src/main/java/org/openapitools/api/PetApi.java:78">
P1: `@Valid` on `ResponseEntity` validates the wrapper, not its body, so returned `Pet` values are not validated; the nested collection elements are likewise unreachable. Add a body-aware cascade rather than marking only the wrapper.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeClassnameTestApiDelegate.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeClassnameTestApiDelegate.java:36">
P2: This cascades validation on the `ResponseEntity`, not its `Client` body, so returned `Client` instances are not validated. Validate the body explicitly or provide a cascade-capable `ResponseEntity` extractor; otherwise omit this annotation.</violation>
</file>

<file name="samples/client/petstore/spring-http-interface-reactive-bean-validation/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/client/petstore/spring-http-interface-reactive-bean-validation/src/main/java/org/openapitools/api/StoreApi.java:83">
P1: This cascades validation on the `Mono` wrapper, not its emitted `ResponseEntity` body, so invalid returned `Order` values remain unchecked. Validate the emitted response body through a reactive-aware validation path instead.</violation>
</file>

<file name="samples/openapi3/server/petstore/spring-boot-springdoc/src/main/java/org/openapitools/api/UserApi.java">

<violation number="1" location="samples/openapi3/server/petstore/spring-boot-springdoc/src/main/java/org/openapitools/api/UserApi.java:208">
P1: This annotation cascades into the `ResponseEntity`, not its `User` body, so returned users are never validated. Validate the extracted body or provide a `ResponseEntity` value extractor before claiming response-model validation.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-3-include-http-request-context/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-3-include-http-request-context/src/main/java/org/openapitools/api/StoreApi.java:136">
P2: This cascades validation into the `ResponseEntity` wrapper, not its unannotated body, so response-model constraints are never checked. Annotate the body type and provide a `ResponseEntity` value extractor, or omit this validation claim for this mode.</violation>
</file>

<file name="samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/client/petstore/spring-http-interface-useHttpServiceProxyFactoryInterfacesConfigurator/src/main/java/org/openapitools/api/PetApi.java:86">
P1: The nested `@Valid Pet` requires return-value validation to traverse `ResponseEntity`, but no `ValueExtractor` is registered for that wrapper, so validation fails instead of reaching the collection elements. Remove the nested cascade from both collection returns or provide a `ResponseEntity` extractor.</violation>
</file>

<file name="samples/openapi3/client/petstore/spring-cloud-3/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/openapi3/client/petstore/spring-cloud-3/src/main/java/org/openapitools/api/PetApi.java:71">
P1: `@Valid` cascades into the `ResponseEntity` bean, not its `Pet` body, so this scalar response's model constraints are never checked. The nested collection annotation likewise needs a `ResponseEntity` value extractor to reach its elements; provide extraction support before claiming response validation for these signatures.</violation>
</file>

<file name="samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/StoreApiDelegate.java">

<violation number="1" location="samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/StoreApiDelegate.java:65">
P2: This cascades validation to the `ResponseEntity` wrapper, not its `Order` body, so returned orders are not validated. Expose and cascade the body (for example, with a `ResponseEntity` value extractor and `@Valid` on the type argument) or validate it another way.</violation>
</file>

<file name="samples/server/petstore/spring-boot-defaultInterface-unhandledExcp/src/main/java/org/openapitools/api/AnotherFakeApi.java">

<violation number="1" location="samples/server/petstore/spring-boot-defaultInterface-unhandledExcp/src/main/java/org/openapitools/api/AnotherFakeApi.java:63">
P2: This annotates the `ResponseEntity` return value, not its `Client` body, so the returned model is not validated. Remove `@Valid` from `ResponseEntity` signatures unless a `ValueExtractor` is provided.</violation>
</file>

<file name="samples/openapi3/client/petstore/spring-cloud/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/openapi3/client/petstore/spring-cloud/src/main/java/org/openapitools/api/PetApi.java:137">
P1: `@Valid` here cascades into the `ResponseEntity` bean, not its `body`, so the returned list and its `Pet` elements are not validated. Add a `ValueExtractor` for `ResponseEntity` and place `@Valid` on its type argument, or use another supported unwrapping path.</violation>
</file>

<file name="samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/StoreApi.java:127">
P1: These annotations cascade into the `ResponseEntity` object, not its body, so returned models and maps are never validated. Add a supported body-unwrapping path or omit `@Valid` until one exists.</violation>
</file>

<file name="samples/openapi3/server/petstore/spring-boot-springdoc/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/openapi3/server/petstore/spring-boot-springdoc/src/main/java/org/openapitools/api/PetApi.java:78">
P2: This cascades validation to the `ResponseEntity`, not its `Pet` body, so the returned model is never validated. Cascade onto the body through a supported `ResponseEntity` extractor or otherwise expose the payload to validation.</violation>

<violation number="2" location="samples/openapi3/server/petstore/spring-boot-springdoc/src/main/java/org/openapitools/api/PetApi.java:164">
P1: Cascading to `Pet` here requires traversing `ResponseEntity`'s type argument, but no `ResponseEntity` value extractor is provided. Return-value validation can fail with a missing-extractor error instead of validating the list; use a supported way to unwrap the response body before cascading.</violation>
</file>

<file name="samples/client/petstore/spring-http-interface-springboot-4/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/client/petstore/spring-http-interface-springboot-4/src/main/java/org/openapitools/api/StoreApi.java:79">
P2: This cascades into the `ResponseEntity` bean, not its `OrderDto` body, so returned models and the inventory map remain unvalidated. Validate the body with a `ResponseEntity`-aware mechanism; otherwise this does not provide the advertised response-body validation.</violation>
</file>

<file name="samples/openapi3/server/petstore/spring-boot-oneof-sealed/src/main/java/org/openapitools/api/FooApi.java">

<violation number="1" location="samples/openapi3/server/petstore/spring-boot-oneof-sealed/src/main/java/org/openapitools/api/FooApi.java:70">
P1: This cascades into the `ResponseEntity` bean, not its body, so the returned `FooRefOrValue` is never validated. The collection annotation has the same gap; cascade through the wrapper or avoid presenting these annotations as response-body validation.</violation>
</file>

<file name="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/PetApi.java:143">
P1: These annotations do not validate the response bodies: the method-level `@Valid` cascades into `ResponseEntity`, not `Pet`, while reaching the nested list/set elements requires a `ResponseEntity` value extractor. Provide/register that extractor and annotate the payload, or avoid emitting these annotations for `ResponseEntity` responses.</violation>
</file>

<file name="samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/PetApiDelegate.java">

<violation number="1" location="samples/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/PetApiDelegate.java:70">
P1: These nested cascades still require Bean Validation to extract `ResponseEntity`’s type argument before reaching the pets, so validating either return value fails without a `ResponseEntity` `ValueExtractor`. Suppress nested cascades for this wrapper or provide the extractor.</violation>
</file>

<file name="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/StoreApi.java:98">
P2: These annotations cascade validation onto the `ResponseEntity`, not its body, so the returned map and `Order` objects remain unvalidated without a `ResponseEntity` value extractor. Remove `@Valid` from these wrappers or cascade on the payload through a supported extractor.</violation>
</file>

<file name="samples/client/petstore/spring-http-interface-reactive-bean-validation/src/main/java/org/openapitools/api/UserApi.java">

<violation number="1" location="samples/client/petstore/spring-http-interface-reactive-bean-validation/src/main/java/org/openapitools/api/UserApi.java:123">
P1: This annotates the `Mono<ResponseEntity<User>>` return wrapper, not the decoded `User`; Bean Validation cannot traverse these wrappers without value extractors. Validate the model after unwrapping the response or provide the required extractors.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-3-include-http-request-context/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-3-include-http-request-context/src/main/java/org/openapitools/api/PetApi.java:147">
P1: This annotates the `ResponseEntity` return rather than its body, and the nested `@Valid Pet` requires a `ResponseEntity` value extractor to reach the list elements. As a result, response models are not validated (and nested return-value validation may fail); add body-aware validation or stop emitting these annotations for `ResponseEntity` returns.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-source/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-source/src/main/java/org/openapitools/api/StoreApi.java:89">
P2: This does not validate the returned `Order`: `@Valid` cascades into `ResponseEntity` itself, not its body. Add supported body traversal and annotate the body type, or omit this ineffective annotation when `useResponseEntity` is enabled.</violation>
</file>

<file name="samples/openapi3/server/petstore/spring-boot-oneof-interface/src/main/java/org/openapitools/api/FooApi.java">

<violation number="1" location="samples/openapi3/server/petstore/spring-boot-oneof-interface/src/main/java/org/openapitools/api/FooApi.java:108">
P1: This nested cascade requires Bean Validation to extract the `List` from `ResponseEntity`, but no `ResponseEntity` `ValueExtractor` exists; return-value validation therefore fails instead of validating the elements. Add a supported extractor or avoid cascading through this wrapper.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/UserApiDelegate.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/UserApiDelegate.java:92">
P1: `@Valid` cascades on the returned `ResponseEntity`, not through its body, so this signature never validates the returned `User`. Use a return-validation strategy that reaches the body.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-4/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-4/src/main/java/org/openapitools/api/StoreApi.java:140">
P2: This cascades validation onto the `ResponseEntity`, not its body, so the returned `Order` is never validated. Apply cascading to the body with a `ResponseEntity` `ValueExtractor`, or validate the body explicitly; the same issue affects the other two signatures.</violation>
</file>

<file name="samples/openapi3/server/petstore/spring-boot-oneof/src/main/java/org/openapitools/api/FooApi.java">

<violation number="1" location="samples/openapi3/server/petstore/spring-boot-oneof/src/main/java/org/openapitools/api/FooApi.java:108">
P1: The nested `@Valid` still requires traversing `ResponseEntity<T>` to reach list elements, but no `ValueExtractor` exists for `ResponseEntity`; return-value validation therefore fails. Suppress nested validation for `useResponseEntity` or provide an extractor.</violation>
</file>

<file name="samples/openapi3/client/petstore/spring-stubs/src/main/java/org/openapitools/api/UserApi.java">

<violation number="1" location="samples/openapi3/client/petstore/spring-stubs/src/main/java/org/openapitools/api/UserApi.java:208">
P1: This only cascades validation to the `ResponseEntity` wrapper; it does not validate the `User` in its body. Add a mechanism that cascades into the response body, or omit this annotation rather than implying the returned model is validated.</violation>
</file>

<file name="samples/client/petstore/spring-cloud/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/client/petstore/spring-cloud/src/main/java/org/openapitools/api/PetApi.java:71">
P1: This `@Valid` cascades into the `ResponseEntity` bean, not its body, so returned `Pet` values are not validated. Provide a cascade path to the unwrapped body (for example, a supported `ResponseEntity` value extractor and type-argument annotation); this annotation alone does not enable the advertised validation.</violation>
</file>

<file name="samples/client/petstore/spring-cloud-deprecated/src/main/java/org/openapitools/api/UserApi.java">

<violation number="1" location="samples/client/petstore/spring-cloud-deprecated/src/main/java/org/openapitools/api/UserApi.java:189">
P2: `@Valid` cascades on the outer `ResponseEntity`, so return-value validation never reaches the `User` body. Emit `@Valid` on the body type with a `ResponseEntity` value extractor, or omit this annotation for wrapped responses; the same placement on `loginUser` cannot validate its `String` body either.</violation>
</file>

<file name="samples/client/petstore/spring-cloud-tags/src/main/java/org/openapitools/api/PetController.java">

<violation number="1" location="samples/client/petstore/spring-cloud-tags/src/main/java/org/openapitools/api/PetController.java:206">
P1: `@Valid` cascades into the returned `ResponseEntity`, not its `Pet` body, so this endpoint never validates the returned model. Cascade the payload with a `ResponseEntity` value extractor or validate the body explicitly.</violation>
</file>

<file name="samples/server/petstore/springboot-implicitHeaders-annotationLibrary/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/server/petstore/springboot-implicitHeaders-annotationLibrary/src/main/java/org/openapitools/api/StoreApi.java:89">
P2: `@Valid` cascades the `ResponseEntity` itself, not its `Order` body, so invalid returned models are never validated. Emit a supported cascade into the body or avoid presenting this wrapper annotation as response validation.</violation>
</file>

<file name="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeApiDelegate.java">

<violation number="1" location="samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/FakeApiDelegate.java:75">
P1: `@Valid` cascades on the returned `ResponseEntity`, not its `OuterComposite` body, so this signature does not validate the returned model. Add a `ResponseEntity` value extractor and annotate the type argument, or explicitly validate the unwrapped body.</violation>
</file>

<file name="samples/openapi3/client/petstore/spring-cloud-3-with-optional/src/main/java/org/openapitools/api/UserApi.java">

<violation number="1" location="samples/openapi3/client/petstore/spring-cloud-3-with-optional/src/main/java/org/openapitools/api/UserApi.java:113">
P1: `@Valid` cascades into the `ResponseEntity` instance, not its generic body, so this does not validate the returned `User`. Add a supported cascade into the body (for example, a `ResponseEntity` value extractor) or omit this annotation rather than implying the response model is validated.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/StoreApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/StoreApi.java:134">
P1: `@Valid` here cascades into the `ResponseEntity`, not its body, so returned `Order` values are not validated. Add a supported cascade from `ResponseEntity` to its body (for example, a value extractor plus a type-use `@Valid`) or avoid emitting this annotation as response-body validation.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApiDelegate.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApiDelegate.java:75">
P1: `@Valid` here cascades into the returned `ResponseEntity`, not its generic body, so `OuterComposite` is never validated. Do not emit this annotation for `ResponseEntity<T>` unless a supported body-cascading path is provided.</violation>
</file>

<file name="samples/client/petstore/spring-http-interface-springboot-4/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/client/petstore/spring-http-interface-springboot-4/src/main/java/org/openapitools/api/PetApi.java:85">
P1: The nested `@Valid` requires traversal through `ResponseEntity`, for which this configuration has no value extractor, so return-value validation fails for these collection methods. Remove the nested `@Valid` here and in `findPetsByTags`.</violation>
</file>

<file name="samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/client/petstore/spring-cloud-feign-without-url/src/main/java/org/openapitools/api/PetApi.java:71">
P1: `@Valid` cascades into the `ResponseEntity` bean, not its generic body, so the returned `Pet` is never validated. Add a cascade path to the body, such as a `ResponseEntity` `ValueExtractor`, before emitting this annotation.</violation>
</file>

<file name="samples/server/petstore/springboot-beanvalidation-no-nullable/src/main/java/org/openapitools/api/FakeApi.java">

<violation number="1" location="samples/server/petstore/springboot-beanvalidation-no-nullable/src/main/java/org/openapitools/api/FakeApi.java:144">
P1: This cascades validation on the `ResponseEntity` wrapper, not its `OuterComposite` body, so the returned model is never validated. Use a return-value cascade that reaches the body, with the required `ResponseEntity` value-extraction support.</violation>
</file>

<file name="samples/client/petstore/spring-http-interface-reactive-bean-validation/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/client/petstore/spring-http-interface-reactive-bean-validation/src/main/java/org/openapitools/api/PetApi.java:130">
P1: This annotates the returned `Mono`, not its emitted `Pet`, so scalar response models are never cascaded through `ResponseEntity`. Add a supported cascade for the decoded response body instead of marking only the outer return value.</violation>
</file>

<file name="samples/openapi3/client/petstore/spring-cloud-oas3-fakeapi/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/openapi3/client/petstore/spring-cloud-oas3-fakeapi/src/main/java/org/openapitools/api/PetApi.java:137">
P1: The return-level `@Valid` cascades into the `ResponseEntity`, not its body; the nested `Pet` cascade still requires a `ResponseEntity` value extractor to reach the payload. Register an extractor and cascade the payload type argument so these response models are actually validated.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/PetApi.java:143">
P1: The nested `@Valid` still requires a `ValueExtractor` for `ResponseEntity` to reach the `Pet` elements, despite leaving the immediate type argument unannotated. Add/register that extractor or omit the nested cascade for `ResponseEntity` returns; the `Set` signature has the same issue.</violation>
</file>

<file name="samples/client/petstore/spring-cloud-tags/src/main/java/org/openapitools/api/StoreController.java">

<violation number="1" location="samples/client/petstore/spring-cloud-tags/src/main/java/org/openapitools/api/StoreController.java:127">
P1: This cascades validation into the returned `ResponseEntity`, not its unannotated body, so `Order` and map values remain unvalidated with `useResponseEntity`. Add a `ResponseEntity` value extractor or another mechanism that cascades validation to `getBody()`.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-delegate/src/main/java/org/openapitools/api/FakeApi.java:138">
P1: This cascades validation into the `ResponseEntity` wrapper, not its `OuterComposite` body, so the returned model's constraints are never checked. Use a supported body-validation strategy for wrapped responses, or omit this ineffective annotation.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-4/src/main/java/org/openapitools/api/PetApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-4/src/main/java/org/openapitools/api/PetApi.java:273">
P1: This cascades into the `ResponseEntity` wrapper, not its `Pet` body, so the returned model is never validated. Add a supported cascade path to the body, or omit `@Valid` for this wrapper rather than implying that response validation works.</violation>
</file>

<file name="samples/openapi3/server/petstore/springboot-4-jspecify-useOptional/src/main/java/org/openapitools/api/RequiredAndNullableApi.java">

<violation number="1" location="samples/openapi3/server/petstore/springboot-4-jspecify-useOptional/src/main/java/org/openapitools/api/RequiredAndNullableApi.java:67">
P2: This `@Valid` cascades on the returned `ResponseEntity`, not its body, so `RequiredAndNullable` is never validated. Add a supported cascade path to the body (for example, a `ValueExtractor`); otherwise this annotation does not provide response-model validation.</violation>
</file>

Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Requires human review: Auto-approval blocked because this review re-detected 2 unresolved issues already reported by Cubic.

View guided diff | Re-trigger cubic

contentType = "application/json"
)
ResponseEntity<OuterCompositeDto> fakeOuterCompositeSerialize(
@Valid ResponseEntity<OuterCompositeDto> fakeOuterCompositeSerialize(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: @Valid cascades into the ResponseEntity, not its generic body, so this does not validate the returned OuterCompositeDto. Handle the body with supported unwrapping; annotating the wrapper cannot validate the payload.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/client/petstore/spring-http-interface-springboot-4/src/main/java/org/openapitools/api/FakeApi.java, line 92:

<comment>`@Valid` cascades into the `ResponseEntity`, not its generic body, so this does not validate the returned `OuterCompositeDto`. Handle the body with supported unwrapping; annotating the wrapper cannot validate the payload.</comment>

<file context>
@@ -89,7 +89,7 @@ ResponseEntity<Boolean> fakeOuterBooleanSerialize(
         contentType = "application/json"
     )
-    ResponseEntity<OuterCompositeDto> fakeOuterCompositeSerialize(
+    @Valid ResponseEntity<OuterCompositeDto> fakeOuterCompositeSerialize(
          @Valid @RequestBody(required = false) @Nullable OuterCompositeDto outerCompositeDto
     );
</file context>

produces = { "application/xml", "application/json" }
)
default ResponseEntity<User> getUserByName(
default @Valid ResponseEntity<User> getUserByName(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: This @Valid cascades on ResponseEntity, not its body; the unannotated User type argument means response model constraints are never checked. Add a supported body-cascade mechanism or omit this annotation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/server/petstore/springboot-delegate-j8/src/main/java/org/openapitools/api/UserApi.java, line 188:

<comment>This `@Valid` cascades on `ResponseEntity`, not its body; the unannotated `User` type argument means response model constraints are never checked. Add a supported body-cascade mechanism or omit this annotation.</comment>

<file context>
@@ -185,7 +185,7 @@ default ResponseEntity<Void> deleteUser(
         produces = { "application/xml", "application/json" }
     )
-    default ResponseEntity<User> getUserByName(
+    default @Valid ResponseEntity<User> getUserByName(
         @Parameter(name = "username", description = "The name that needs to be fetched. Use user1 for testing.", required = true, in = ParameterIn.PATH) @PathVariable("username") String username
     ) {
</file context>

consumes = "application/json"
)
ResponseEntity<Pet> addPet(
@Valid ResponseEntity<Pet> addPet(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: This cascades validation into the ResponseEntity wrapper, not its Pet body, so returned models are not validated. Cascade into the payload and provide a supported way to unwrap ResponseEntity during validation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/openapi3/client/petstore/spring-stubs-skip-default-interface/src/main/java/org/openapitools/api/PetApi.java, line 71:

<comment>This cascades validation into the `ResponseEntity` wrapper, not its `Pet` body, so returned models are not validated. Cascade into the payload and provide a supported way to unwrap `ResponseEntity` during validation.</comment>

<file context>
@@ -68,7 +68,7 @@ public interface PetApi {
         consumes = "application/json"
     )
-    ResponseEntity<Pet> addPet(
+    @Valid ResponseEntity<Pet> addPet(
         @Parameter(name = "Pet", description = "Pet object that needs to be added to the store", required = true) @Valid @RequestBody Pet pet
     ) throws Exception;
</file context>

produces = { "application/xml", "application/json" }
)
default ResponseEntity<Pet> getPetById(
default @Valid ResponseEntity<Pet> getPetById(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: This cascades into the ResponseEntity wrapper, not its Pet body, so the returned model is never validated. Add a supported cascade path to the body, or omit @Valid for this wrapper rather than implying that response validation works.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/openapi3/server/petstore/springboot-4/src/main/java/org/openapitools/api/PetApi.java, line 273:

<comment>This cascades into the `ResponseEntity` wrapper, not its `Pet` body, so the returned model is never validated. Add a supported cascade path to the body, or omit `@Valid` for this wrapper rather than implying that response validation works.</comment>

<file context>
@@ -270,7 +270,7 @@ default ResponseEntity<List<Pet>> findPetsByTags(
         produces = { "application/xml", "application/json" }
     )
-    default ResponseEntity<Pet> getPetById(
+    default @Valid ResponseEntity<Pet> getPetById(
         @Parameter(name = "petId", description = "ID of pet to return", required = true, in = ParameterIn.PATH) @PathVariable("petId") Long petId
     ) {
</file context>

produces = { "application/xml", "application/json" }
)
default ResponseEntity<Order> getOrderById(
default @Valid ResponseEntity<Order> getOrderById(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: This cascades validation onto the ResponseEntity, not its generic body, so returned models and map elements remain unvalidated. Validate the unwrapped response body or omit this annotation for ResponseEntity signatures unless a suitable value extractor is provided.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/openapi3/server/petstore/springboot-implicitHeaders/src/main/java/org/openapitools/api/StoreApi.java, line 140:

<comment>This cascades validation onto the `ResponseEntity`, not its generic body, so returned models and map elements remain unvalidated. Validate the unwrapped response body or omit this annotation for `ResponseEntity` signatures unless a suitable value extractor is provided.</comment>

<file context>
@@ -137,7 +137,7 @@ default ResponseEntity<Map<String, Integer>> getInventory(
         produces = { "application/xml", "application/json" }
     )
-    default ResponseEntity<Order> getOrderById(
+    default @Valid ResponseEntity<Order> getOrderById(
         @Min(value = 1L) @Max(value = 5L) @Parameter(name = "order_id", description = "ID of pet that needs to be fetched", required = true, in = ParameterIn.PATH) @PathVariable("order_id") Long orderId
     ) {
</file context>

consumes = { "application/json" }
)
default ResponseEntity<RequiredAndNullable> requiredAndNullablePost(
default @Valid ResponseEntity<RequiredAndNullable> requiredAndNullablePost(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This @Valid cascades on the returned ResponseEntity, not its body, so RequiredAndNullable is never validated. Add a supported cascade path to the body (for example, a ValueExtractor); otherwise this annotation does not provide response-model validation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/openapi3/server/petstore/springboot-4-jspecify-useOptional/src/main/java/org/openapitools/api/RequiredAndNullableApi.java, line 67:

<comment>This `@Valid` cascades on the returned `ResponseEntity`, not its body, so `RequiredAndNullable` is never validated. Add a supported cascade path to the body (for example, a `ValueExtractor`); otherwise this annotation does not provide response-model validation.</comment>

<file context>
@@ -64,7 +64,7 @@ default Optional<NativeWebRequest> getRequest() {
         consumes = { "application/json" }
     )
-    default ResponseEntity<RequiredAndNullable> requiredAndNullablePost(
+    default @Valid ResponseEntity<RequiredAndNullable> requiredAndNullablePost(
         @Parameter(name = "RequiredAndNullable", description = "bodyWithRequiredAndNullableAttributes", required = true) @Valid @RequestBody RequiredAndNullable requiredAndNullable
     ) {
</file context>

produces = { "application/xml", "application/json" }
)
default ResponseEntity<Order> getOrderById(
default @Valid ResponseEntity<Order> getOrderById(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This does not validate the returned Order: @Valid cascades into ResponseEntity itself, not its body. Add supported body traversal and annotate the body type, or omit this ineffective annotation when useResponseEntity is enabled.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/openapi3/server/petstore/springboot-source/src/main/java/org/openapitools/api/StoreApi.java, line 89:

<comment>This does not validate the returned `Order`: `@Valid` cascades into `ResponseEntity` itself, not its body. Add supported body traversal and annotate the body type, or omit this ineffective annotation when `useResponseEntity` is enabled.</comment>

<file context>
@@ -86,7 +86,7 @@ default ResponseEntity<Map<String, Integer>> getInventory(
         produces = { "application/xml", "application/json" }
     )
-    default ResponseEntity<Order> getOrderById(
+    default @Valid ResponseEntity<Order> getOrderById(
         @Min(value = 1L) @Max(value = 5L)  @PathVariable("orderId") Long orderId
     ) {
</file context>

produces = { "application/xml", "application/json" }
)
default ResponseEntity<Order> getOrderById(
default @Valid ResponseEntity<Order> getOrderById(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This cascades validation onto the ResponseEntity, not its body, so the returned Order is never validated. Apply cascading to the body with a ResponseEntity ValueExtractor, or validate the body explicitly; the same issue affects the other two signatures.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/openapi3/server/petstore/springboot-4/src/main/java/org/openapitools/api/StoreApi.java, line 140:

<comment>This cascades validation onto the `ResponseEntity`, not its body, so the returned `Order` is never validated. Apply cascading to the body with a `ResponseEntity` `ValueExtractor`, or validate the body explicitly; the same issue affects the other two signatures.</comment>

<file context>
@@ -137,7 +137,7 @@ default ResponseEntity<Map<String, Integer>> getInventory(
         produces = { "application/xml", "application/json" }
     )
-    default ResponseEntity<Order> getOrderById(
+    default @Valid ResponseEntity<Order> getOrderById(
         @Min(value = 1L) @Max(value = 5L) @Parameter(name = "orderId", description = "ID of pet that needs to be fetched", required = true, in = ParameterIn.PATH) @PathVariable("orderId") Long orderId
     ) {
</file context>

produces = { "application/json", "application/xml" }
)
ResponseEntity<User> getUserByName(
@Valid ResponseEntity<User> getUserByName(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: @Valid cascades on the outer ResponseEntity, so return-value validation never reaches the User body. Emit @Valid on the body type with a ResponseEntity value extractor, or omit this annotation for wrapped responses; the same placement on loginUser cannot validate its String body either.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/client/petstore/spring-cloud-deprecated/src/main/java/org/openapitools/api/UserApi.java, line 189:

<comment>`@Valid` cascades on the outer `ResponseEntity`, so return-value validation never reaches the `User` body. Emit `@Valid` on the body type with a `ResponseEntity` value extractor, or omit this annotation for wrapped responses; the same placement on `loginUser` cannot validate its `String` body either.</comment>

<file context>
@@ -186,7 +186,7 @@ ResponseEntity<Void> deleteUser(
         produces = { "application/json", "application/xml" }
     )
-    ResponseEntity<User> getUserByName(
+    @Valid ResponseEntity<User> getUserByName(
         @Parameter(name = "username", description = "The name that needs to be fetched. Use user1 for testing.", required = true, in = ParameterIn.PATH) @PathVariable("username") String username
     );
</file context>

produces = { "application/xml", "application/json" }
)
default ResponseEntity<Order> getOrderById(
default @Valid ResponseEntity<Order> getOrderById(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: @Valid cascades the ResponseEntity itself, not its Order body, so invalid returned models are never validated. Emit a supported cascade into the body or avoid presenting this wrapper annotation as response validation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At samples/server/petstore/springboot-implicitHeaders-annotationLibrary/src/main/java/org/openapitools/api/StoreApi.java, line 89:

<comment>`@Valid` cascades the `ResponseEntity` itself, not its `Order` body, so invalid returned models are never validated. Emit a supported cascade into the body or avoid presenting this wrapper annotation as response validation.</comment>

<file context>
@@ -86,7 +86,7 @@ default ResponseEntity<Map<String, Integer>> getInventory(
         produces = { "application/xml", "application/json" }
     )
-    default ResponseEntity<Order> getOrderById(
+    default @Valid ResponseEntity<Order> getOrderById(
         @Min(value = 1L) @Max(value = 5L)  @PathVariable("orderId") Long orderId
     ) {
</file context>

@LeosBitto

LeosBitto commented Oct 11, 2026 •

Copy link
Copy Markdown
Author

@cubic-dev-ai please reconsider all your comments in this PR with regards to the current description of this PR.

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai please reconsider all your comments in this PR with regards to the currect description of this PR.

@LeosBitto I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 existing issue remains and 1 new issue found across 310 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="modules/openapi-generator/src/main/resources/JavaSpring/responseType.mustache">

<violation number="1" location="modules/openapi-generator/src/main/resources/JavaSpring/responseType.mustache:1">
P2: The `{{^isVoid}}` guard does not exclude primitive/scalar return types, so this change contradicts the PR description's claim that "Primitive and void responses remain unannotated". `SpringCodegen.doDataTypeAssignment` (SpringCodegen.java:1320) sets `isVoid` only when `returnType == null`, so operations whose response is `integer`, `boolean`, `number`, etc. (Java `Integer`, `Long`, `Boolean`, `BigDecimal`) will now be generated as `@Valid Integer getX()` etc. When return-value validation actually runs (e.g., the interface is used with method validation / `@Validated`), Hibernate Validator requires a value extractor for the cascaded scalar type and throws `ConstraintDeclarationException` ("No value extractor found for type") — the same breakage the PR is trying to avoid for wrappers. Exclude primitives with the operation flag; note `beanValidation.mustache` already uses the `{{^isPrimitiveType}}` pattern for exactly this reason.</violation>
</file>

Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.

View guided diff | Re-trigger cubic

@@ -1 +1 @@
{{^vendorExtensions.x-sse}}{{#reactive}}{{#useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{{returnContainer}}}<{{>returnTypes}}>>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{#isArray}}Flux<{{/isArray}}{{>returnTypes}}{{#isArray}}>{{/isArray}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{^useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<{{{returnContainer}}}<{{>returnTypes}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{/reactive}}{{^reactive}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{#responseWrapper}}>{{/responseWrapper}}{{/reactive}}{{/vendorExtensions.x-sse}}{{#vendorExtensions.x-sse}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}{{{returnContainer}}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/vendorExtensions.x-sse}} No newline at end of file
{{#useBeanValidation}}{{^isVoid}}@Valid {{/isVoid}}{{/useBeanValidation}}{{^vendorExtensions.x-sse}}{{#reactive}}{{#useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{{returnContainer}}}<{{>returnTypes}}>>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{#isArray}}Flux<{{/isArray}}{{>returnTypes}}{{#isArray}}>{{/isArray}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{^useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<{{{returnContainer}}}<{{>returnTypes}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{/reactive}}{{^reactive}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{#responseWrapper}}>{{/responseWrapper}}{{/reactive}}{{/vendorExtensions.x-sse}}{{#vendorExtensions.x-sse}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}{{{returnContainer}}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/vendorExtensions.x-sse}} No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The {{^isVoid}} guard does not exclude primitive/scalar return types, so this change contradicts the PR description's claim that "Primitive and void responses remain unannotated". SpringCodegen.doDataTypeAssignment (SpringCodegen.java:1320) sets isVoid only when returnType == null, so operations whose response is integer, boolean, number, etc. (Java Integer, Long, Boolean, BigDecimal) will now be generated as @Valid Integer getX() etc. When return-value validation actually runs (e.g., the interface is used with method validation / @Validated), Hibernate Validator requires a value extractor for the cascaded scalar type and throws ConstraintDeclarationException ("No value extractor found for type") — the same breakage the PR is trying to avoid for wrappers. Exclude primitives with the operation flag; note beanValidation.mustache already uses the {{^isPrimitiveType}} pattern for exactly this reason.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/main/resources/JavaSpring/responseType.mustache, line 1:

<comment>The `{{^isVoid}}` guard does not exclude primitive/scalar return types, so this change contradicts the PR description's claim that "Primitive and void responses remain unannotated". `SpringCodegen.doDataTypeAssignment` (SpringCodegen.java:1320) sets `isVoid` only when `returnType == null`, so operations whose response is `integer`, `boolean`, `number`, etc. (Java `Integer`, `Long`, `Boolean`, `BigDecimal`) will now be generated as `@Valid Integer getX()` etc. When return-value validation actually runs (e.g., the interface is used with method validation / `@Validated`), Hibernate Validator requires a value extractor for the cascaded scalar type and throws `ConstraintDeclarationException` ("No value extractor found for type") — the same breakage the PR is trying to avoid for wrappers. Exclude primitives with the operation flag; note `beanValidation.mustache` already uses the `{{^isPrimitiveType}}` pattern for exactly this reason.</comment>

<file context>
@@ -1 +1 @@
-{{^vendorExtensions.x-sse}}{{#reactive}}{{#useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{{returnContainer}}}<{{>returnTypes}}>>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{#isArray}}Flux<{{/isArray}}{{>returnTypes}}{{#isArray}}>{{/isArray}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{^useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<{{{returnContainer}}}<{{>returnTypes}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{/reactive}}{{^reactive}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{#responseWrapper}}>{{/responseWrapper}}{{/reactive}}{{/vendorExtensions.x-sse}}{{#vendorExtensions.x-sse}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}{{{returnContainer}}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/vendorExtensions.x-sse}}
\ No newline at end of file
+{{#useBeanValidation}}{{^isVoid}}@Valid {{/isVoid}}{{/useBeanValidation}}{{^vendorExtensions.x-sse}}{{#reactive}}{{#useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{{returnContainer}}}<{{>returnTypes}}>>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}Mono<ResponseEntity<{{#isArray}}Flux<{{/isArray}}{{>returnTypes}}{{#isArray}}>{{/isArray}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{^useResponseEntity}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}Mono<{{{returnContainer}}}<{{>returnTypes}}>>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/useResponseEntity}}{{/reactive}}{{^reactive}}{{#responseWrapper}}{{.}}<{{/responseWrapper}}{{#useResponseEntity}}ResponseEntity<{{/useResponseEntity}}{{>returnTypes}}{{#useResponseEntity}}>{{/useResponseEntity}}{{#responseWrapper}}>{{/responseWrapper}}{{/reactive}}{{/vendorExtensions.x-sse}}{{#vendorExtensions.x-sse}}{{#vendorExtensions.x-reactive-return-except-list-of-string}}{{{returnContainer}}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{^vendorExtensions.x-reactive-return-except-list-of-string}}{{#isArray}}Flux{{/isArray}}{{^isArray}}Mono{{/isArray}}<{{>returnTypes}}>{{/vendorExtensions.x-reactive-return-except-list-of-string}}{{/vendorExtensions.x-sse}}
\ No newline at end of file
</file context>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test proving what you have stated? I would like to see the situation causing ConstraintDeclarationException which you have described.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing tests assert generated signatures but do not reproduce runtime validation. I can’t verify the claimed ConstraintDeclarationException from this diff alone; a test exercising method return-value validation for a scalar response would demonstrate whether the finding applies.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REQ] enhance useBeanValidation to generate @Valid for the returned objects too

1 participant