Skip to content

[csharp][generichost] Deserialize present-but-null nullable enums#23912

Open
daberni wants to merge 1 commit into
OpenAPITools:masterfrom
daberni:fix/generichost-nullable-enum-deserialization
Open

[csharp][generichost] Deserialize present-but-null nullable enums#23912
daberni wants to merge 1 commit into
OpenAPITools:masterfrom
daberni:fix/generichost-nullable-enum-deserialization

Conversation

@daberni
Copy link
Copy Markdown
Contributor

@daberni daberni commented May 31, 2026

For a property that is both required and nullable with an enum type, the generichost JsonConverter.Read(...) only assigned the backing Option when the raw JSON string was non-null. An explicit null therefore left the Option unset, and the required-property check then threw ArgumentException: Property is required ... — even though the property was present (just null).

Non-enum nullable properties (string, int, DateTime, …) already assign the Option unconditionally; only the enum branch had the null-skipping guard.

Reproduce

Deserialize a model with a required + nullable enum whose JSON value is null, e.g. RequiredClass with "required_nullable_enum_string": null:

System.ArgumentException : Property is required for class RequiredClass. (Parameter 'requiredNullableEnumString')

Expected: deserializes with the value null.

Fix

csharp/libraries/generichost/JsonConverter.mustache: for the string-enum read, assign the Option unconditionally when the property is nullable, mapping a null raw value to a null enum value. Non-nullable enums keep the existing guard, so their generated output is unchanged (scoped via {{#isNullable}}).

Test

Adds RequiredClassNullableEnumTests to the net8 NullReferenceTypes sample, deserializing RequiredClass with required_nullable_enum_string set to null. It throws before the fix and passes after (verified locally, red→green).

PR checklist

  • Read the contribution guidelines.
  • Pull Request title and description describe the change and how to validate it.
  • Built the project and regenerated the affected samples (./bin/generate-samples.sh ./bin/configs/csharp-generichost-*.yaml); committed all changes. The change is scoped to the generichost C# template, so only generichost samples are affected.
  • Filed against master.
  • No existing issue (searched) — reproduction described above.
  • Technical committee: @devhl-labs (C# GenericHost)

Summary by cubic

Fixes C# generichost deserialization for required nullable enums so a present-but-null value no longer triggers a “Property is required” error. Non-nullable enums are unchanged.

  • Bug Fixes
    • Update csharp/libraries/generichost/JsonConverter.mustache to always set the backing Option for nullable enums, mapping a null raw value to a null enum.
    • Add generator test CSharpClientCodegenTest#testGenericHostNullableEnumDeserializesPresentNull to verify nullable enums accept null and non-nullable enums keep the guard.
    • Regenerate affected generichost samples.

Written for commit 1458996. Summary will update on new commits.

Review in cubic

@daberni daberni marked this pull request as ready for review May 31, 2026 13:55
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 38 files

Re-trigger cubic

@daberni daberni force-pushed the fix/generichost-nullable-enum-deserialization branch from 1eb8d6e to c1ac499 Compare May 31, 2026 14:51
For a property that is both `required` and `nullable` with an enum type, the
generated JsonConverter only assigned the backing Option when the raw JSON
string was non-null. An explicit `null` therefore left the Option unset, and the
required-property check then threw `ArgumentException: Property is required` —
even though the property was present (just null).

Assign the Option unconditionally for nullable enums, mapping a null raw value
to a null enum value. Non-nullable enums keep the existing guard, so their
generated output is unchanged. Regenerated all generichost samples.

Adds CSharpClientCodegenTest#testGenericHostNullableEnumDeserializesPresentNull,
which generates the generichost client and asserts the RequiredClass converter
uses the null-tolerant read for the required+nullable enum while the non-nullable
enum keeps the guard.
@daberni daberni force-pushed the fix/generichost-nullable-enum-deserialization branch from c1ac499 to 1458996 Compare May 31, 2026 15:22
@wing328
Copy link
Copy Markdown
Member

wing328 commented Jun 1, 2026

thanks for the PR

cc @devhl-labs

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants