Skip to content

fix: let explicit @Schema(format) override type-derived format (#5185)#5186

Open
seonwooj0810 wants to merge 1 commit into
swagger-api:masterfrom
seonwooj0810:fix/issue-5185-schema-format-override
Open

fix: let explicit @Schema(format) override type-derived format (#5185)#5186
seonwooj0810 wants to merge 1 commit into
swagger-api:masterfrom
seonwooj0810:fix/issue-5185-schema-format-override

Conversation

@seonwooj0810
Copy link
Copy Markdown

Fixes #5185

Problem

When a field carries an explicit @Schema(format = "...") whose owning type already resolves to a built-in format, the explicit format is silently dropped. The reported case is java.net.URI annotated with @Schema(format = "uri-reference"): the type resolves to format: uri first, and because the schema already has a (type-derived) format, the explicit override is ignored — producing format: uri instead of the requested uri-reference.

@Schema#format is documented as "Provides an optional override for the format", so an explicitly supplied format should win over the one inferred from the property type.

Change

In ModelResolver.resolveSchemaMembers(...) the format was only applied when the schema did not already have one:

if (StringUtils.isNotBlank(format) && StringUtils.isBlank(schema.getFormat())) {
    schema.format(format);
}

This is relaxed so that a non-blank explicit format always takes precedence over a type-derived format:

if (StringUtils.isNotBlank(format)) {
    schema.format(format);
}

This fixes the uri-reference case in #5185 and any other type whose explicit @Schema(format) differs from its inferred format, without needing a per-type enum entry. A field with no explicit @Schema(format) still falls back to the type-derived format (e.g. plain URIuri).

Tests

Added Ticket5185Test covering both OpenAPI 3.0 and 3.1 resolution:

  • @Schema(format = "uri-reference") URI resolves to format: uri-reference
  • a plain URI (no annotation) still resolves to format: uri

Test evidence

Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 -- in io.swagger.v3.core.resolving.Ticket5185Test

Full swagger-core module suite after the change:

Tests run: 689, Failures: 0, Errors: 0, Skipped: 0
BUILD SUCCESS

Verification done: (1) No in-flight PR — gh pr list --search "5185" / "uri-reference" returned none; no open PR touches this path. (2) No active claim — issue is unassigned and has no claim comments. (3) Code-focused — change is in ModelResolver.java plus a Java test. (4) Bug still present on master — the guarded condition is unchanged at ModelResolver line 3184. (5) No parent epic closing this. Branch is based directly on current master (no rebase needed).

Note: the issue suggested adding a dedicated URI_REFERENCE PrimitiveType enum entry. This PR instead fixes the root cause — explicit @Schema(format) should always override the inferred format — which covers uri-reference and any future explicit-override case with a smaller, more general change. Happy to switch to the enum-based approach if maintainers prefer it.

@VadimKobyakov
Copy link
Copy Markdown

I am not a maintainer but I feel a little unwell with this "global" fix. It does fix my issue, but it might allow for unintended behavior of the resolving. For example, I might annotate a int field with @Schema(format = "email") and the resolver would allow it. On the other hand, the 3.1 version allows that out of the box. A maintainer should look into that I just wanted to voice my concerns

@ewaostrowska ewaostrowska force-pushed the fix/issue-5185-schema-format-override branch from 3caa575 to 1f6b0eb Compare June 2, 2026 12:02
…er-api#5185)

`@Schema(format = "uri-reference")` on a `java.net.URI` field was ignored
because `resolveSchemaMembers` only applied the annotation format when the
schema had no format yet. For `java.net.URI` the `PrimitiveType` already sets
`format: uri`, so the user-specified `uri-reference` was dropped.

An explicit `format` on `@Schema` expresses the user's intent and must take
precedence over a format derived from the property type. A URI field without
an explicit format still resolves to the default `uri`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ewaostrowska ewaostrowska force-pushed the fix/issue-5185-schema-format-override branch from 1f6b0eb to f67b8a0 Compare June 2, 2026 12:11
@seonwooj0810
Copy link
Copy Markdown
Author

Thanks for raising this, @VadimKobyakov — it's a fair point to think through.

I'd argue the broader behavior is actually correct here. In both OpenAPI and JSON Schema, format is an open-ended annotation keyword: it's informational and explicitly not coupled to type-level validation. The spec allows custom/arbitrary format values, and validators are free to ignore ones they don't recognize. So @Schema(format = "email") on an int isn't something the resolver is expected to reject — that's a user-authoring choice, the same way it already is in 3.1 (as you noted).

The @Schema#format javadoc also describes it as "an optional override for the format", which reads as explicit user intent that should win over the type-derived default.

swagger-core doesn't validate format/type compatibility anywhere else either, so adding a type-vs-format gate just for this path would be inconsistent and arguably out of scope for the resolver. This change only makes 3.0 behave like 3.1 already does.

That said, I fully agree a maintainer should make the final call. If they'd prefer a narrower fix (e.g. a dedicated URI_REFERENCE PrimitiveType entry as the original issue suggested), I'm happy to switch to that approach.

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.

[Bug]: @Schema with format = "uri-reference" on java.net.URI field resolves to format: uri when using ModelConverters

2 participants