.Net: fix: prevent duplicate "null" in JSON Schema type arrays for nullable parameters#13635
Merged
SergeyMenshykh merged 4 commits intoJun 16, 2026
Conversation
… parameters
InsertNullTypeIfRequired() 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.
This produces invalid schemas like ["string", "null", "null"] for
Nullable<T> parameters with = null defaults, causing HTTP 400 from
OpenAI's strict-mode API.
The fix replaces .Contains() with a value-based .Any() check, following
the existing pattern used in NormalizeAdditionalProperties in the same
file.
Fixes microsoft#13527
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a strict-mode JSON Schema sanitization bug in the OpenAI connector where nullable parameters could end up with duplicate "null" entries in the schema type array (e.g. ["string","null","null"]), causing schema validation failures in strict mode.
Changes:
- Fixes
InsertNullTypeIfRequired()to detect an existing"null"entry by value (instead ofJsonArray.Contains()reference equality) before adding"null". - Adds regression tests to cover both trigger paths (optional parameter insertion +
nullable: truekeyword) and the positive insertion case.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| dotnet/src/Connectors/Connectors.OpenAI/Core/OpenAIFunction.cs | Prevents duplicate "null" insertion by switching to a value-based scan of the type array. |
| dotnet/src/Connectors/Connectors.OpenAI.UnitTests/Core/OpenAIFunctionTests.cs | Adds unit tests to ensure "null" is not duplicated and is inserted when missing in strict-mode sanitization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
westey-m
approved these changes
Jun 15, 2026
rogerbarreto
approved these changes
Jun 15, 2026
peibekwe
approved these changes
Jun 15, 2026
The ToFunctionDefinition method parameter has always been named 'allowStrictSchemaAdherence', not 'strict'. Fix the named argument in the three new test methods to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
rogerbarreto
approved these changes
Jun 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
InsertNullTypeIfRequired()producing duplicate"null"entries in JSON Schema type arrays (e.g.,["string", "null", "null"]) forNullable<T>parameters with= nulldefaultsJsonArray.Contains()) with value-based.Any()checkRoot Cause
InsertNullTypeIfRequired()inOpenAIFunction.csusesjsonArray.Contains(NullType)to check for existing"null"entries before adding one.JsonArray.Contains()comparesJsonNodeobjects by reference equality —JsonNodedoes not overrideEquals(). TheNullTypeconstant ("null") creates a newJsonNodeon implicit conversion, so the guard always fails and"null"is always added as a duplicate.For
Nullable<T>parameters with= nulldefaults,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:
IsRequired = false) →insertNullType = true"nullable": truekeywordChanges
dotnet/src/Connectors/Connectors.OpenAI/Core/OpenAIFunction.csjsonArray.Contains(NullType)with value-based.Any()check (follows existing pattern inNormalizeAdditionalProperties)dotnet/src/Connectors/Connectors.OpenAI.UnitTests/Core/OpenAIFunctionTests.csnullablekeyword, positive case (null inserted when absent)Testing
ItDoesNotInsertDuplicateNullInTypeArrayForOptionalParameter— schema with pre-existing["string", "null"]+IsRequired = falseItDoesNotInsertDuplicateNullInTypeArrayForNullableKeyword— schema with"nullable": true+IsRequired = trueItInsertsNullInTypeArrayWhenAbsent— schema with["string"]only →"null"correctly addedFixes #13527