Skip to content

fix: don't add an empty property for a required @JsonUnwrapped member (OpenAPI 3.1) - #5361

Merged
daniel-kmiecik merged 3 commits into
swagger-api:3.0.0from
bnasslahsen:fix/jackson3-model-resolution
Oct 27, 2026
Merged

daniel-kmiecik merged 3 commits into
swagger-api:3.0.0from
bnasslahsen:fix/jackson3-model-resolution

Conversation

@bnasslahsen

Copy link
Copy Markdown

Pull Request

Description

Found while porting springdoc-openapi to Swagger Core 3.0 (feedback in #4991).

With OpenAPI 3.1, a @JsonUnwrapped member also annotated with @Schema(requiredMode = REQUIRED) leaves an empty
property in the model, listed in required too, next to the unwrapped properties. With records, Jackson 3
additionally exposes the component as a synthetic @JsonUnwrapped/<n> creator property, which gets the same
treatment:

public record Example(
        @JsonUnwrapped @Schema(requiredMode = REQUIRED) Inner inner,
        @Schema(requiredMode = REQUIRED) Integer number) {
    public record Inner(@Schema(requiredMode = REQUIRED) String value) {}
}
# before (OpenAPI 3.1)
properties: {value: {type: string}, inner: {}, number: {...}, '@JsonUnwrapped/0': {}}
required: ['@JsonUnwrapped/0', inner, number, value]
# after
properties: {value: {type: string}, number: {...}}
required: [number, value]

Cause: the jsonUnwrappedHandler merges the inner properties and returns null. Then, with OpenAPI 3.1,
getSchemaFromAnnotation rebuilds a schema from the remaining @Schema annotation, and that schema is added as a
property. The fix stops processing the member once the handler has unwrapped it: 7 lines in ModelResolver.

The OpenAPI 3.0 output is unchanged; it was already correct.

Fixes:

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • ♻️ Refactor (non-breaking change)
  • 🧪 Tests
  • 📝 Documentation
  • 🧹 Chore (build or tooling)

Checklist

  • I have added/updated tests as needed: JacksonJsonUnwrappedTest, covering a record and a class with OpenAPI 3.1
  • I have added/updated documentation where applicable: not needed
  • The PR title is descriptive
  • The code builds and passes tests locally: swagger-core and swagger-rest, on Jackson 3.2.3
  • I have linked related issues (if any): [Feature] Support Jackson 3.x release line #4991

… (OpenAPI 3.1)

With OpenAPI 3.1, a @JsonUnwrapped property annotated with
@Schema(requiredMode = REQUIRED) left an empty property in the model,
also listed in "required", next to the unwrapped properties. With
records, Jackson 3 additionally exposes the component as a synthetic
"@JsonUnwrapped/<n>" creator property, which got the same treatment:

  properties: value, inner: {}, number, '@JsonUnwrapped/0': {}
  required: ['@JsonUnwrapped/0', inner, number, value]

Once the jsonUnwrappedHandler has merged the unwrapped properties, the
member is no longer resolved from its remaining annotations. OpenAPI 3.0
output is unchanged.

See swagger-api#4991.

Signed-off-by: Badr NASS LAHSEN <badr.nasslahsen@gmail.com>
@daniel-kmiecik
daniel-kmiecik merged commit 9ee4aa3 into swagger-api:3.0.0 Oct 27, 2026
8 checks passed
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.

2 participants