Skip to content

fix(plugin): skip auto-generated response decorator when Api*Response already present#3803

Merged
kamilmysliwiec merged 1 commit into
nestjs:masterfrom
maruthang:fix/issue-1639-api-found-response-200
Apr 9, 2026
Merged

fix(plugin): skip auto-generated response decorator when Api*Response already present#3803
kamilmysliwiec merged 1 commit into
nestjs:masterfrom
maruthang:fix/issue-1639-api-found-response-200

Conversation

@maruthang
Copy link
Copy Markdown
Contributor

Summary

Fixes #1639

Bug: @ApiFoundResponse (and other @Api*Response decorators) were being ignored by the plugin, which always appended a default ApiResponse decorator with status 200/201, overriding the explicit response decorator.

Root Cause: addDecoratorToNode in controller-class.visitor.ts unconditionally appended an auto-generated ApiResponse decorator regardless of whether the method already had an explicit @Api*Response decorator.

Fix: Added a check — if any existing decorator name matches ApiResponse exactly or matches the Api*Response pattern, the auto-generated default is skipped entirely.

Changes

  • lib/plugin/visitors/controller-class.visitor.ts: Added hasExplicitApiResponseDecorator check before creating the auto-generated response decorator; only appends it when no explicit @Api*Response is present.
  • test/plugin/fixtures/app.controller.ts: Updated existing snapshot fixture to reflect the corrected output.
  • test/plugin/fixtures/app.controller-api-response.ts: New fixture with a method decorated with @ApiFoundResponse to serve as regression test input.
  • test/plugin/controller-class-visitor.spec.ts: New regression test that verifies no extra 200 response is added when @ApiFoundResponse is already present.

Testing

  • Added regression test in test/plugin/controller-class-visitor.spec.ts that verifies no auto-generated 200 response is injected when @ApiFoundResponse is already present on a method.
  • All existing tests pass (159 passing).

@kamilmysliwiec kamilmysliwiec merged commit 1f7fc4f into nestjs:master Apr 9, 2026
1 check passed
@PeterTheOne
Copy link
Copy Markdown

This unfortunately seems to have caused a regression: #3862

@kamilmysliwiec
Copy link
Copy Markdown
Member

cc @maruthang

PeterTheOne pushed a commit to PeterTheOne/swagger that referenced this pull request Apr 27, 2026
…Response decorators are present

PR nestjs#3803 added a guard that suppresses the auto-inferred default response
whenever any `Api*Response` decorator is present on a handler. The guard
doesn't distinguish success (2xx) from error (4xx/5xx) decorators, so a
handler with only `@ApiUnauthorizedResponse()` (or any other error-status
decorator) loses its auto-inferred 2xx in the OpenAPI spec. Downstream
client generators (NSwag, openapi-generator, ...) then treat the real
2xx response as an exception at runtime.

Scope the guard to decorators whose status code is below 400 so error
factories no longer suppress the default. The success/redirect case the
original PR fixed (`@ApiFoundResponse` on a `@Redirect()` handler)
continues to work — 302 is still below 400.

Status codes are derived from the decorator name via the same
`Api${PascalCase(HttpStatus key)}Response` convention the factories are
generated from in `api-response.decorator.ts`. Unknown names
(`ApiDefaultResponse`, user-defined) fall back to the previous behavior
(treated as explicit).

Closes nestjs#3862
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adding @ApiFoundResponse on a dynamic redirect method still renders a 200 response code in the OpenAPI contract

3 participants