Skip to content

System.Text.Json can't serialize nested closed hierarchies #132660

Closed

Description

@andrewlock

Description

Using the InferClosedTypePolymorphism in preview 7, there seems to be no way to serialize a closed hierarchy that contains multiple closed types?

e.g. given a hierarchy like this:

Pet (closed)
 |___ Cat
 |___ Dog (closed)
      |___ Labrador
      |___ Collie

then if you try to serialize a Pet instance you get an exception:

System.InvalidOperationException: Specified type 'Dog' is not a supported
derived type for the polymorphic type 'Pet'. Derived types must not be open
generic type definitions, must be assignable to the base type and cannot be 
abstract classes or interfaces unless 'JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor' 
is specified.

That seems like a big limitation? 🤔

Reproduction Steps

The following simple program reproduces the issue:

Pet data = new Labrador();
var opts = new JsonSerializerOptions { InferClosedTypePolymorphism = true };
string serialized = JsonSerializer.Serialize(data, opts);

// Type definitions
closed class Pet {}
sealed class Cat : Pet { }

closed class Dog : Pet { }
sealed class Labrador : Dog { }
sealed class Collie : Dog { }

Expected behavior

I would expect that the Pet to recursively know about all it's descendants given it's a closed hierarchy. I can understand that this can't always be possible (if you have unsealed types for example), but in the example above, the hierarchy is completely defined?

Actual behavior

System.InvalidOperationException: Specified type 'Dog' is not a supported
derived type for the polymorphic type 'Pet'. Derived types must not be open
generic type definitions, must be assignable to the base type and cannot be 
abstract classes or interfaces unless 'JsonUnknownDerivedTypeHandling.FallBackToNearestAncestor' 
is specified.

Regression?

No, this is new functionality

Known Workarounds

I couldn't find a way to make this work with InferClosedTypePolymorphism. The only approach I could find was to fallback to manually specify the derived types on Pet, i.e. manually do what I expected the feature to do

[JsonDerivedType(typeof(Collie), typeDiscriminator: nameof(Collie))]
[JsonDerivedType(typeof(Labrador), typeDiscriminator: nameof(Labrador))]
[JsonDerivedType(typeof(Cat), typeDiscriminator: nameof(Cat))]
public closed class Pet

Configuration

❯ dotnet --version
11.0.100-preview.7.26381.103

Windows 11, x64

Other information

Related to #125449

Activity

  1. added a commit that references this issue on Aug 23, 2026
  2. added this to the 11.0.0 milestone on Aug 27, 2026
  3. added a commit that references this issue on Sep 1, 2026
    818ad35
  4. andrewlock commented on Sep 1, 2026

    @andrewlock
    ContributorAuthor

    Thanks @eiriktsarpalis! 🙏

  5. locked and limited conversation to collaborators on Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions