Skip to content

Fix TypeFactory.CreateCSharpType crash on self-referencing models#10060

Merged
JoshLove-msft merged 2 commits intomainfrom
copilot/fix-typefactory-crash-self-referencing-models
Mar 17, 2026
Merged

Fix TypeFactory.CreateCSharpType crash on self-referencing models#10060
JoshLove-msft merged 2 commits intomainfrom
copilot/fix-typefactory-crash-self-referencing-models

Conversation

Copy link
Contributor

Copilot AI commented Mar 17, 2026

CreateCSharpType crashes with ArgumentException (duplicate key in Dictionary.Add) when processing self-referencing models like QueryFilter { and?: QueryFilter[] }. Re-entrant calls from CreateCSharpTypeCoreCreateModel → property resolution → CreateCSharpType(same type) cache the result before the outer call attempts Add.

  • Fix: Changed TypeCache.Add(inputType, type) to TypeCache[inputType] = type — idempotent on re-entrant writes. Matches the pattern already used by CreateModel (line 190).
  • Test: Added CreateCSharpType_SelfReferencingModel_DoesNotThrow that simulates the re-entrant call path and asserts no exception.
Original prompt

This section details on the original issue you should resolve

<issue_title>TypeFactory.CreateCSharpType crashes on self-referencing models (re-entrant Dictionary.Add)</issue_title>
<issue_description>## Bug Description

TypeFactory.CreateCSharpType crashes with System.ArgumentException: An item with the same key has already been added when processing self-referencing models — models that contain an array property of their own type (e.g. QueryFilter with property and: QueryFilter[]).

Root Cause

CreateCSharpType caches resolved types in TypeCache (a Dictionary<InputType, CSharpType?>). When it encounters a self-referencing model:

  1. Outer call: CreateCSharpType(QueryFilter) → cache miss → calls CreateCSharpTypeCore
  2. CreateCSharpTypeCoreCreateModelBuildProperties → encounters and: QueryFilter[]
  3. Inner (re-entrant) call: CreateCSharpType(QueryFilter) → cache miss again (outer hasn't added yet) → CreateCSharpTypeCore → resolves → TypeCache.Add(QueryFilter, ...) succeeds
  4. Outer call resumes: tries TypeCache.Add(QueryFilter, ...) → 💥 throws because the key was already added by the inner call

Affected Models (example from Azure CostManagement)

  • QueryFilter (properties: and: QueryFilter[], or: QueryFilter[])
  • ForecastFilter (same pattern)
  • ReportConfigFilter (same pattern)
  • ErrorDetail (property: details: ErrorDetail[])

Any ARM/data-plane service with recursive models will trigger this crash.

Reproduction

  1. Create a TypeSpec model with a self-referencing array property:
    model QueryFilter {
      and?: QueryFilter[];
      or?: QueryFilter[];
    }
  2. Run the C# emitter/generator against it
  3. Observe the ArgumentException crash in TypeFactory.CreateCSharpType</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

… re-entrant calls for self-referencing models

Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service bot added emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp labels Mar 17, 2026
@JoshLove-msft JoshLove-msft marked this pull request as ready for review March 17, 2026 14:57
Copilot AI changed the title [WIP] Fix TypeFactory.CreateCSharpType crash on self-referencing models Fix TypeFactory.CreateCSharpType crash on self-referencing models Mar 17, 2026
@JoshLove-msft JoshLove-msft enabled auto-merge March 17, 2026 15:00
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 17, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@10060

commit: 580b05d

@JoshLove-msft JoshLove-msft added this pull request to the merge queue Mar 17, 2026
Merged via the queue into main with commit 5c07285 Mar 17, 2026
25 checks passed
@JoshLove-msft JoshLove-msft deleted the copilot/fix-typefactory-crash-self-referencing-models branch March 17, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeFactory.CreateCSharpType crashes on self-referencing models (re-entrant Dictionary.Add)

3 participants