Skip to content

[http-client-csharp] Fix spread model parameter matching to use wire name#10111

Open
JoshLove-msft wants to merge 1 commit intomicrosoft:mainfrom
JoshLove-msft:fix/spread-model-null-params
Open

[http-client-csharp] Fix spread model parameter matching to use wire name#10111
JoshLove-msft wants to merge 1 commit intomicrosoft:mainfrom
JoshLove-msft:fix/spread-model-null-params

Conversation

@JoshLove-msft
Copy link
Contributor

@JoshLove-msft JoshLove-msft commented Mar 22, 2026

Problem

When generating convenience methods with spread model construction, parameters were matched between the convenience method and the model constructor by C# name. This fails when:

  • @clientName\ renames a property (e.g., spec name \model\ → C# name \OverrideModelName)
  • @Encodedname\ wire names leak into parameter names (e.g., \ ool_resources\ vs \ oolResources)
  • PascalCase vs camelCase differences between the convenience parameter and constructor parameter

Unmatched parameters fell back to \default\ (null), causing \NullReferenceException\ during serialization when \Optional.IsCollectionDefined(null)\ returns \ rue\ for null collections.

This was discovered while migrating \Azure.AI.Agents.Persistent\ to the new @azure-typespec/http-client-csharp\ emitter — 172 out of 261 tests failed with NRE in serialization.

Fix

Match spread parameters by their wire (serialized) name (\WireInfo.SerializedName) instead of C# name. Both the convenience parameter and model constructor parameter share the same wire name since they represent the same JSON field. Uses \TryAdd\ to handle potential duplicate wire names gracefully.

Validation

  • Generator builds with 0 errors
  • Regenerated \Azure.AI.Agents.Persistent\ \ThreadRuns.cs\ — all spread parameters now properly forwarded (previously 5 parameters were \default, now only \�dditionalBinaryDataProperties\ is \default\ which is correct)

@microsoft-github-policy-service microsoft-github-policy-service bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Mar 22, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 22, 2026

Open in StackBlitz

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

commit: 875c063

@github-actions
Copy link
Contributor

No changes needing a change description found.

When constructing spread models in convenience methods, the parameter
matching between convenience method parameters and model constructor
parameters used C# names which can diverge due to:
- @clientName renames (e.g., 'model' -> 'OverrideModelName')
- @Encodedname wire names leaking (e.g., 'tool_resources' vs 'toolResources')
- PascalCase vs camelCase differences

This caused unmatched parameters to fall back to 'default' (null),
leading to NullReferenceException during serialization when
Optional.IsCollectionDefined(null) returns true for null collections.

Fix: match by the property's wire (serialized) name, which is stable
across both the convenience parameter and the model property since
they represent the same JSON field.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft JoshLove-msft force-pushed the fix/spread-model-null-params branch from 875c063 to 6eb86ca Compare March 22, 2026 19:23
@JoshLove-msft JoshLove-msft changed the title fix: use case-insensitive matching for spread model parameter lookup [http-client-csharp] Fix spread model parameter matching to use wire name Mar 22, 2026
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.

1 participant