Skip to content

Microsoft.Extensions.Validation.ValidationsGenerator - static properties cause circular reference #66691

Description

@RichardD2

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I have an API project using .NET 10, and I am trying to move from controllers to minimal APIs.

One of my model classes includes static properties which return pre-configured instances of the model.

With a controller endpoint, this works as expected.

With a minimal API endpoint, every call fails with a "Maximum validation depth of 32 exceeded" error.

This is because the Microsoft.Extensions.Validation.ValidationsGenerator is generating code to validate the static properties, which results in infinite recursion.

Expected Behavior

The generated validation code should only validate instance properties, and ignore static properties.

Steps To Reproduce

Model:

public class MyModel
{
    public int Foo { get; set; }
    
    public static MyModel TheAnswer => new() { Foo = 42 };
}

Controller endpoint:

[Route("[controller]")
public class MyController : ControllerBase
{
    [HttpPost("[action]")]
    public Ok<string> Echo(MyModel model) => $"The answer is {model.Foo}.";
}

Minimal API endpoint:

app.MapGet("MyController/Echo", (MyModel model) => TypedResults.Ok($"The answer is {model.Foo}."));

Source generator output:

if (type == typeof(global::MyNamespace.MyModel))
{
    validatableInfo = new GeneratedValidatableTypeInfo(
        type: typeof(global::MyNamespace.MyModel),
        members: [
            new GeneratedValidatablePropertyInfo(
                containingType: typeof(global::MyNamespace.MyModel),
                propertyType: typeof(global::MyNamespace.MyModel),
                name: "TheAnswer",
                displayName: "TheAnswer"
            ),
        ]
    );
    return true;
}

Exceptions (if any)

 System.InvalidOperationException: Maximum validation depth of 32 exceeded at 'TheAnswer.TheAnswer.TheAnswer....TheAnswer' in 'MyModel'. 
This is likely caused by a circular reference in the object graph. 
Consider increasing the MaxDepth in ValidationOptions if deeper validation is required.
    at Microsoft.Extensions.Validation.ValidatableTypeInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
    at Microsoft.Extensions.Validation.ValidatablePropertyInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
    at Microsoft.Extensions.Validation.ValidatableTypeInfo.ValidateMembersAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
    at Microsoft.Extensions.Validation.ValidatableTypeInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
    at Microsoft.Extensions.Validation.ValidatablePropertyInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
    at Microsoft.Extensions.Validation.ValidatableTypeInfo.ValidateMembersAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
    ...

.NET Version

10.0.300

Anything else?

ASP.NET Core v10.0.8

Visual Studio 2026 v18.6.0

dotnet --info:

.NET SDK:
 Version:           10.0.300
 Commit:            caa81fa497
 Workload version:  10.0.300-manifests.e0989437
 MSBuild version:   18.6.3+caa81fa49

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.26200
 OS Platform: Windows
 RID:         win-x64
 Base Path:   C:\Program Files\dotnet\sdk\10.0.300\

.NET workloads installed:
 [maui-windows]
   Installation Source: VS 18.6.11806.211
   Manifest Version:    10.0.20/10.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maui\10.0.20\WorkloadManifest.json
   Install Type:              Msi

 [maccatalyst]
   Installation Source: VS 18.6.11806.211
   Manifest Version:    26.2.10233/10.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.maccatalyst\26.2.10233\WorkloadManifest.json
   Install Type:              Msi

 [ios]
   Installation Source: VS 18.6.11806.211
   Manifest Version:    26.2.10233/10.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.ios\26.2.10233\WorkloadManifest.json
   Install Type:              Msi

 [android]
   Installation Source: VS 18.6.11806.211
   Manifest Version:    36.1.43/10.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.sdk.android\36.1.43\WorkloadManifest.json
   Install Type:              Msi

 [wasm-tools]
   Installation Source: VS 18.6.11806.211
   Manifest Version:    10.0.108/10.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\10.0.100\microsoft.net.workload.mono.toolchain.current\10.0.108\WorkloadManifest.json
   Install Type:              Msi

Configured to use workload sets when installing new manifests.
No workload sets are installed. Run "dotnet workload restore" to install a workload set.

Host:
  Version:      10.0.8
  Architecture: x64
  Commit:       94ea82652c

.NET SDKs installed:
  10.0.300 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.27 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 9.0.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 10.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.27 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 9.0.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 10.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.27 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 9.0.16 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 10.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]
    registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables:
  Not set

global.json file:
  Not found

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcbugThis issue describes a behavior which is not expected - a bug.

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions