Skip to content

Fix #3275: prevent @Nullable $ref field from mutating shared component schema type#3295

Open
s-chan-o wants to merge 1 commit into
springdoc:mainfrom
s-chan-o:fix/nullable-ref-schema-mutation
Open

Fix #3275: prevent @Nullable $ref field from mutating shared component schema type#3295
s-chan-o wants to merge 1 commit into
springdoc:mainfrom
s-chan-o:fix/nullable-ref-schema-mutation

Conversation

@s-chan-o
Copy link
Copy Markdown

Problem

When a record field is annotated with @Nullable and its type resolves to a $ref (i.e. another component schema), swagger-core 2.2.44 mutates the shared Schema instance stored in the components map by setting types = {"null"}. This causes the referenced schema (e.g. Inner) to lose its original type: "object" declaration and appear as type: "null" in the final OpenAPI output.

Reproducer (OAS 3.1):

public record Inner(int lines, long bytes, String bucket, String key) {}
public record Outer(String id, @Nullable Inner result) {}

Before fix – Inner schema in components:

"Inner": { "type": "null", "properties": { ... } }

Fix

In AbstractOpenApiResource.handleComponentSchemaTypes(), call the new helper SpringDocUtils.fixNullMutatedObjectSchema() which restores any component schema whose types was wrongly reduced to {"null"} when it still has properties (i.e. it is clearly an object).

After fix:

"Inner": { "type": "object", "properties": { ... } }

Test

Added regression test SpringDocApp175Test (OAS 3.1, javadoc variant) with:

  • Inner record (the referenced schema)
  • Outer record with @Nullable Inner result
  • NullableRefController exposing GET /outer
  • Expected snapshot results/3.1.0/app175.json asserting Inner has type: "object"

Also bumped test sub-module pom.xml versions from 2.8.17-SNAPSHOT2.8.18-SNAPSHOT to match the root pom after the maven-release-plugin iteration bump.

Fixes #3275

… component schema type

When swagger-core 2.2.44 processes a @nullable field whose type resolves to
a $ref, it mutates the shared Schema instance in the components map by
setting types = {"null"}. This causes the referenced schema (e.g. Inner) to
lose its original type:"object" and appear as type:"null" in the final output.

Fix: in handleComponentSchemaTypes(), call
SpringDocUtils.fixNullMutatedObjectSchema() which restores any component
schema whose type was wrongly reduced to "null"-only when it still has
properties (i.e. it is an object).

Also fix test sub-module pom.xml versions from 2.8.17-SNAPSHOT to
2.8.18-SNAPSHOT to match the root pom after the maven-release-plugin bump.
@Mattias-Sehlstedt
Copy link
Copy Markdown
Contributor

Mattias-Sehlstedt commented May 28, 2026

Note: I am only a contributor to this project, and not associated with it


I strongly disagree with this PR being merged. The issue is entirely tied to swagger-core, and there is a suggested fix there.

Rather than merging temporary logic to this repository and having to manage the lifecycle and removal of it, I would suggest that you instead inject the fix locally on your end while waiting for the upstream adjustment (with a custom Resolver bean for example).

@s-chan-o
Copy link
Copy Markdown
Author

Thank you for the context, @Mattias-Sehlstedt — that's a fair point architecturally.

I checked swagger-api/swagger-core#5124 and it is currently labeled backlog with no assigned reviewer or milestone, so the timeline for an upstream fix is unclear.

In the meantime, users on Spring Boot 4 + swagger-core 2.2.44 are hitting this silently — component schemas resolve to type: null with no obvious error, which is hard to diagnose.

I'll leave the final call to the maintainer: if a temporary guard in handleComponentSchemaTypes is acceptable until the upstream fix lands, I'm happy to iterate on the implementation. If the preference is to wait for swagger-core, I'll close this PR accordingly.

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

Labels

None yet

Projects

None yet

2 participants