From f7bab0ff9be33dda21dc667c10c34ceec7cfff4f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:45:57 +0000 Subject: [PATCH 1/2] Initial plan From 580b05d6675b21f79563e7a86c465c17bbcbc1f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:55:34 +0000 Subject: [PATCH 2/2] fix: use indexer assignment in TypeFactory.CreateCSharpType to handle re-entrant calls for self-referencing models Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --- .../src/TypeFactory.cs | 2 +- .../test/TypeFactoryTests.cs | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs index a6454ee6f79..12c7fea1699 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/TypeFactory.cs @@ -51,7 +51,7 @@ protected internal TypeFactory() } type = CreateCSharpTypeCore(inputType); - TypeCache.Add(inputType, type); + TypeCache[inputType] = type; return type; } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs index 557d08a7a7f..174c1c24eb2 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/TypeFactoryTests.cs @@ -283,6 +283,30 @@ public void CreateEnum_ExtensibleEnumWithoutVisitorsOrCustomCode_ReturnsExtensib Assert.IsTrue(enumProvider!.IsExtensible); } + [Test] + public void CreateCSharpType_SelfReferencingModel_DoesNotThrow() + { + var selfRefModel = InputFactory.Model("QueryFilter"); + var isReentrant = false; + + MockHelpers.LoadMockGenerator(createCSharpTypeCore: (InputType inputType) => + { + if (inputType == selfRefModel && !isReentrant) + { + isReentrant = true; + // Simulate the re-entrant call that occurs with self-referencing models + // (e.g., QueryFilter with property and: QueryFilter[]). + // CreateCSharpTypeCore -> CreateModel -> BuildProperties -> CreateCSharpType(same model) + CodeModelGenerator.Instance.TypeFactory.CreateCSharpType(selfRefModel); + } + return typeof(object); + }); + + // Before the fix, this would throw ArgumentException: + // "An item with the same key has already been added" + Assert.DoesNotThrow(() => CodeModelGenerator.Instance.TypeFactory.CreateCSharpType(selfRefModel)); + } + /// /// Test visitor that modifies enum namespaces to end with ".Models" ///