Commit 7fd75c3
.Net: fix: prevent duplicate "null" in JSON Schema type arrays for nullable parameters (#13635)
## Summary
- Fixes `InsertNullTypeIfRequired()` producing duplicate `"null"`
entries in JSON Schema type arrays (e.g., `["string", "null", "null"]`)
for `Nullable<T>` parameters with `= null` defaults
- Replaces reference-equality guard (`JsonArray.Contains()`) with
value-based `.Any()` check
- Adds 3 regression tests covering both trigger paths and positive
insertion
## Root Cause
`InsertNullTypeIfRequired()` in `OpenAIFunction.cs` uses
`jsonArray.Contains(NullType)` to check for existing `"null"` entries
before adding one. `JsonArray.Contains()` compares `JsonNode` objects by
reference equality — `JsonNode` does not override `Equals()`. The
`NullType` constant (`"null"`) creates a new `JsonNode` on implicit
conversion, so the guard always fails and `"null"` is always added as a
duplicate.
For `Nullable<T>` parameters with `= null` defaults,
`AIJsonUtilities.CreateJsonSchema()` correctly produces `["string",
"null"]`. The strict-mode sanitizer then attempts to add `"null"` again
— the broken guard lets it through, producing `["string", "null",
"null"]`.
Two trigger paths reach the same bug:
1. Optional parameters (`IsRequired = false`) → `insertNullType = true`
2. Schemas with `"nullable": true` keyword
## Changes
| File | Change |
|------|--------|
| `dotnet/src/Connectors/Connectors.OpenAI/Core/OpenAIFunction.cs` |
Replace `jsonArray.Contains(NullType)` with value-based `.Any()` check
(follows existing pattern in `NormalizeAdditionalProperties`) |
|
`dotnet/src/Connectors/Connectors.OpenAI.UnitTests/Core/OpenAIFunctionTests.cs`
| 3 new tests: duplicate prevention for optional params, duplicate
prevention for `nullable` keyword, positive case (null inserted when
absent) |
## Testing
- 3 new unit tests added covering:
- `ItDoesNotInsertDuplicateNullInTypeArrayForOptionalParameter` — schema
with pre-existing `["string", "null"]` + `IsRequired = false`
- `ItDoesNotInsertDuplicateNullInTypeArrayForNullableKeyword` — schema
with `"nullable": true` + `IsRequired = true`
- `ItInsertsNullInTypeArrayWhenAbsent` — schema with `["string"]` only →
`"null"` correctly added
Fixes #13527
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
Co-authored-by: SergeyMenshykh <sergemenshikh@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent f8c757b commit 7fd75c3
2 files changed
Lines changed: 68 additions & 1 deletion
File tree
- dotnet/src/Connectors
- Connectors.OpenAI.UnitTests/Core
- Connectors.OpenAI/Core
Lines changed: 66 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
299 | 299 | | |
300 | 300 | | |
301 | 301 | | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
302 | 368 | | |
303 | 369 | | |
304 | 370 | | |
| |||
Lines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
313 | 313 | | |
314 | 314 | | |
315 | 315 | | |
316 | | - | |
| 316 | + | |
| 317 | + | |
317 | 318 | | |
318 | 319 | | |
319 | 320 | | |
| |||
0 commit comments