Skip to content

[http-client-csharp] Resolve GA date-time name ownership for projected properties #11783

Open

Description

@live1206

Description

The GA date-time name preservation added by #11773 determines whether a historical contract name is already claimed by checking sibling properties from inputProperty.EnclosingType. That is correct for ordinary model properties, but the input enclosing model is not necessarily the TypeProvider that emits a projected or flattened property.

This can produce two incorrect ownership decisions:

  1. A sibling exists on the source wire model but is not projected onto the target provider. The unprojected sibling can incorrectly block preservation of an otherwise available GA name.
  2. Properties from different source wire models are projected onto the same target provider. They cannot see each other through their respective input models and can both claim the same contract name.

Conceptually:

Wire model A: startTime -> projected onto ResourceData
Wire model A: startOn   -> not projected
GA ResourceData: StartOn
Expected projected name: StartOn

and:

Wire model A: startTime -> projected onto ResourceData
Wire model B: startOn   -> projected onto ResourceData
GA ResourceData: StartOn
Expected names: StartsOn, StartOn

Why this is deferred

PropertyProvider has the source InputProperty and target TypeProvider during construction, but the target provider's complete property collection is not available yet. Reading enclosingType.Properties at that point would recursively invoke property construction.

A prototype in #11773 split candidate discovery from provider-level reconciliation after BuildProperties(). Although it handled synthetic projected cases, it introduced lifecycle complexity because providers, constructors, serialization providers, and downstream visitors can materialize or transform property identities at different stages. The actual management-plane flattening implementation also lives in Azure.Generator.Management, so MTG-only synthetic coverage does not validate the real integration path.

Expected behavior

Historical date-time names should be checked against members actually emitted on the target provider, not all siblings from the source wire model. Resolution must happen before constructor parameters and serialization providers consume the final property names.

Suggested direction

  • Add integration coverage using the management-plane FlattenPropertyVisitor/FlattenedPropertyProvider path.
  • Decide whether ownership should be handled by:
    • a provider-level name reservation/reconciliation phase with a clearly defined lifecycle; or
    • a narrow API allowing a projecting generator to provide the actual projected property set or historical-name candidates.
  • Preserve ordinary non-projected behavior from [http-client-csharp] Preserve shipped date-time property names #11773.

Regression coverage

Cover both:

  1. An unprojected source sibling does not block a GA name on the target provider.
  2. Properties projected from different input models onto one target provider cannot both claim the same GA name.

Follow-up to #11773.

- by copilot

Activity

  1. github-actions commented on Aug 28, 2026

    @github-actions
    Contributor

    🎯 Issue Triage

    Follow-up bug tracking incorrect GA date-time name ownership when properties are projected or flattened in the C# HTTP client emitter. The current sibling-check logic from #11773 uses the source wire model's enclosing type rather than the target provider's actual property set.

    Category: Bug
    Area: emitter:client:csharp

    ⚠️ No reproduction provided. This is a tracking/design issue with conceptual examples rather than a runnable repro.

    🔍 Analysis
    • Root cause: inputProperty.EnclosingType is used to detect name conflicts, but for projected/flattened properties, the target TypeProvider may have a different property set than the source wire model.
    • Two failure modes identified:
      1. An unprojected source sibling blocks a valid GA name on the target provider.
      2. Properties from different wire models projected onto the same provider both claim the same GA name.
    • Deferred reason: Target provider's complete property collection isn't available during PropertyProvider construction — reading it would cause recursive construction.
    • Affected area: Azure.Generator.Management, specifically FlattenPropertyVisitor/FlattenedPropertyProvider.
    • Follow-up to: [http-client-csharp] Preserve shipped date-time property names #11773
    📝 Suggested next steps
    • Add integration test coverage using the management-plane FlattenPropertyVisitor/FlattenedPropertyProvider path.
    • Decide ownership resolution approach: provider-level name reservation/reconciliation phase vs. narrow API for projected property sets.
    • Ensure regression coverage for both identified failure modes (unprojected sibling blocking, and dual-claim from different wire models).
    • Preserve existing non-projected behavior from [http-client-csharp] Preserve shipped date-time property names #11773.

    Generated by Agentic Triage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingemitter:client:csharpIssue for the C# client emitter: @typespec/http-client-csharp

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions