Record deserialization fails to parse the legitimate null value when it comes from the nested single case union.
For example, if you have a type setup like this:
type MyRecord =
{ MyUnion: MyUnion }
and MyUnion = MyUnion of int voption
and you serialize a value with the None case and then try to deserialization it back {"MyUnion":null} it will fail, because of the null: "Unhandled exception. System.Text.Json.JsonException: MyRecord.MyUnion was expected to be of type MyUnion, but was null."
When deserializing records, properties are checked for null values, whether they are allowed. Some types, like unit, option, etc are always allowed to be null. But what the current check fails to consider is that if you unwrap single-case single-field unions that contain other nullable types, such as options, they will also be represented as nulls. So you have to check not only for nullable types, but whether they are RECURSIVELY wrapped inside single-case single-field unions when unwrapping is enabled in the options.
Record deserialization fails to parse the legitimate null value when it comes from the nested single case union.
For example, if you have a type setup like this:
and you serialize a value with the None case and then try to deserialization it back
{"MyUnion":null}
it will fail, because of the null: "Unhandled exception. System.Text.Json.JsonException: MyRecord.MyUnion was expected to be of type MyUnion, but was null."When deserializing records, properties are checked for null values, whether they are allowed. Some types, like unit, option, etc are always allowed to be null. But what the current check fails to consider is that if you unwrap single-case single-field unions that contain other nullable types, such as options, they will also be represented as nulls. So you have to check not only for nullable types, but whether they are RECURSIVELY wrapped inside single-case single-field unions when unwrapping is enabled in the options.