Skip to content

Fix handling of nullable enums for 3.0#2920

Open
Youssef1313 wants to merge 2 commits into
microsoft:mainfrom
Youssef1313:nullable-enum
Open

Fix handling of nullable enums for 3.0#2920
Youssef1313 wants to merge 2 commits into
microsoft:mainfrom
Youssef1313:nullable-enum

Conversation

@Youssef1313

Copy link
Copy Markdown
Member

Previously, this scenario wasn't producing a type and wasn't producing a null value in the enum array.

This fixes it so that they are produced.

In the future, we could also avoid adding a oneOf with a single element in this scenario.

@Youssef1313 Youssef1313 requested a review from a team as a code owner July 1, 2026 16:35
Comment thread src/Microsoft.OpenApi/Models/OpenApiSchema.cs Fixed
Comment thread src/Microsoft.OpenApi/Models/OpenApiSchema.cs Fixed
inferredType = inferredAnyOf ?? inferredType;

hasOneOfNullAndSingleEnumWith3_0 = nullInOneOf && effectiveOneOf is { Count: 1 } &&
effectiveOneOf[0].Enum is { Count: > 0 };

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.

should this be count > 1 because enum values will have null and at least one enum value? Maybe I am wrong

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's valid (and more correct) to not have null in the enum array. We are dealing with something like:

"oneOf": [
  {
    "type": "null"
  },
  {
    "enum": [
      // ...
    ]
  }
]

The enum array could have a single element, and in all reasonable practical use cases, it must not have null, because then null becomes invalid as it matches both child schemas.

Note that the above shape is draft 2020-12, which isn't what we emit for OpenAPI 3.0. However, the OpenApiSchema model is designed more towards the 2020-12 draft.

That's why we can't emit the thing as-is and we have to do lots of special casing for versions. So, we emit the exact shape above that I mentioned for 3.1 and 3.2 which use 2020-12. But the same OpenApiSchema model serializes differently for 3.0 because it's not really using 2020-12 draft and the above shape isn't valid for OpenAPI 3.0.

That's at least how I'm understanding things currently.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

valid yes. More correct, not really. Each keyword is evaluated independently, the instance needs to validate one of the keywords. And enums are effectively oneOf consts. We could argue it's easier to ready though.

@Youssef1313 Youssef1313 Jul 2, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@baywet

What I mean is something like:

"oneOf": [
  {
    "type": "null"
  },
  {
    "enum": [
      "A",
      "B",
      null
    ]
  }
]

In this case, null matches both child schemas. And so, oneOf fails and null won't be considered valid.

See https://www.jsonschemavalidator.net/s/bdAKMMTl

So my point is that a schema like the above is pointless.

Comment thread src/Microsoft.OpenApi/Models/OpenApiSchema.cs Outdated
Comment thread src/Microsoft.OpenApi/Models/OpenApiSchema.cs
Comment thread src/Microsoft.OpenApi/Models/OpenApiSchema.cs Outdated
Comment thread test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs Outdated
Comment thread test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs Outdated
Comment thread test/Microsoft.OpenApi.Tests/Models/OpenApiSchemaTests.cs
Comment on lines +1103 to +1119
foreach (var enumValue in schema.Enum)
{
if (enumValue is not null)
{
var currentType = enumValue.GetValueKind() switch
{
JsonValueKind.Array => JsonSchemaType.Array,
JsonValueKind.String => JsonSchemaType.String,
JsonValueKind.Number => JsonSchemaType.Number,
JsonValueKind.True or JsonValueKind.False => JsonSchemaType.Boolean,
JsonValueKind.Null => (JsonSchemaType)0,
_ => JsonSchemaType.Object,
};

commonType |= currentType;
}
}
@Youssef1313 Youssef1313 requested a review from baywet July 2, 2026 12:17

@baywet baywet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you for making the changes!

@Youssef1313

Copy link
Copy Markdown
Member Author

@baywet Is there anything remaining to get this merged? Would we have a new version released before .NET 11 Preview 7 so that we try to get that in aspnetcore repo and possibly build some fixes on our side on top of this?

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.

4 participants