microsoft / microsoft/agent-framework
.NET: [Bug]: AddAGUIServer writes explicit nulls on the AG-UI wire with AGUI 0.0.6 (rejected by @ag-ui/client)
@westey-m is already working on this.
Since Aug 31, 2026.
- Dominant language
- Python
- Stars
- 13.6k
- Forks
- 2.3k
- Avg merge
- 2d 45m
- Merged PRs (30d)
- 358
Description
### Description
`AddAGUIServer()` registers the AG-UI wire types through `AGUIJsonSerializerContext.Default.Options.TypeInfoResolver`. AGUI 0.0.6 moved the "omit a property that has no value" rule off that resolver. In 0.0.5 the rule came from `DefaultIgnoreCondition` on the context's own options; in 0.0.6 it lives on the new `AGUIJsonUtilities.DefaultTypeInfoResolver`, which applies it per property with a type-info modifier so it travels with the resolver into other `JsonSerializerOptions`.
The consequence, for an app on hosting 1.17–1.19 with AGUI.Server / AGUI.Abstractions raised to 0.0.6, is that every SSE event goes out with explicit nulls for its optional fields:
```
data: {"type":"RUN_STARTED","threadId":"…","runId":"…","parentRunId":null,"input":null,"timestamp":null,"rawEvent":null,"metadata":null}
```
The AG-UI TypeScript client (`@ag-ui/client` 0.0.59) declares those fields optional, not nullable, so it rejects the first event and the whole run fails client-side:
```
ZodError: [
{ "code": "invalid_type", "expected": "string", "received": "null", "path": ["parentRunId"] },
{ "code": "invalid_type", "expected": "object", "received": "null", "path": ["input"] },
…
]
```
`AGUIJsonUtilities`' own doc comment names this exact failure — "would start writing `"parentMessageId": null` and similar — the exact wire divergence that receiving SDKs have had to be patched to tolerate" — and tells integrators to compose `AGUIJsonUtilities.DefaultTypeInfoResolver` rather than the context directly.
This is not visible in this repo's own CI today because `dotnet/Directory.Packages.props` pins the AGUI packages at 0.0.5. It becomes the default behavior the moment that pin moves to 0.0.6.
**Suggested fix** — in `ConfigureAGUIJsonOptions.Configure`:
```diff
chain.Add(AgentAbstractionsJsonUtilities.DefaultOptions.TypeInfoResolver!);
-chain.Add(AGUIJsonSerializerContext.Default.Options.TypeInfoResolver!);
+chain.Add(AGUIJsonUtilities.DefaultTypeInfoResolver);
```
`AGUIJsonUtilities.DefaultTypeInfoResolver` is `AGUIJsonSerializerContext.Default` with the omit-empty modifier attached, so it resolves the same types and only changes what is written for properties with no value. It is new in 0.0.6, so this line and the package bump have to land together.
### Code Sample
```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAGUIServer();
builder.AddAIAgent("agent", (sp, name) => new ChatClientAgent(chatClient, new ChatClientAgentOptions { Name = name }));
var app = builder.Build();
app.MapAGUIServer("/ag-ui", app.Services.GetRequiredKeyedService("agent"));
app.Run();
```
With `AGUI.Server` / `AGUI.Abstractions` raised to 0.0.6, `curl -N -H 'Accept: text/event-stream' …` on that endpoint shows `"timestamp": null`, `"metadata": null`, `"parentRunId": null` and `"input": null` on the events. With 0.0.5 the same fields are omitted.
Workaround for anyone hitting this before the fix lands — put the modified resolver first in the chain, after `AddAGUIServer()`:
```csharp
builder.Services.Configure(options =>
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AGUIJsonUtilities.DefaultTypeInfoResolver));
```
### Error Messages / Stack Traces
```shell
Agent execution failed: ZodError: [
{ "code": "invalid_type", "expected": "number", "received": "null", "path": ["timestamp"], "message": "Expected number, received null" },
{ "code": "invalid_type", "expected": "object", "received": "null", "path": ["metadata"], "message": "Expected object, received null" },
{ "code": "invalid_type", "expected": "string", "received": "null", "path": ["parentRunId"], "message": "Expected string, received null" },
{ "code": "invalid_type", "expected": "object", "received": "null", "path": ["input"], "message": "Expected object, received null" }
]
```
### Package Versions
- `Microsoft.Agents.AI.Hosting.AGUI.AspNetCore` 1.17.0-preview.260804.1 (the same code is in 1.19.0-preview.260822.1 and on `main`)
- `AGUI.Server` / `AGUI.Abstractions` 0.0.6
- `Microsoft.Extensions.AI` 10.8.3
- Client: `@ag-ui/client` 0.0.59
### .NET Version
net10.0
### Additional Context
Both current hosting previews (1.17, 1.19) declare AGUI 0.0.5, so `ConfigureAGUIJsonOptions` and the AGUI package version have to move together for the wire format to stay unchanged.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.