Skip to content

.Net: fix: prevent duplicate "null" in JSON Schema type arrays for nullable parameters#13635

Open
roli-lpci wants to merge 1 commit intomicrosoft:mainfrom
roli-lpci:fix/json-schema-duplicate-null-type
Open

.Net: fix: prevent duplicate "null" in JSON Schema type arrays for nullable parameters#13635
roli-lpci wants to merge 1 commit intomicrosoft:mainfrom
roli-lpci:fix/json-schema-duplicate-null-type

Conversation

@roli-lpci
Copy link

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

… 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>
@roli-lpci roli-lpci requested a review from a team as a code owner March 5, 2026 18:42
@moonbox3 moonbox3 added .NET Issue or Pull requests regarding .NET code kernel Issues or pull requests impacting the core kernel labels Mar 5, 2026
@github-actions github-actions bot changed the title fix: prevent duplicate "null" in JSON Schema type arrays for nullable parameters .Net: fix: prevent duplicate "null" in JSON Schema type arrays for nullable parameters Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kernel Issues or pull requests impacting the core kernel .NET Issue or Pull requests regarding .NET code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.Net: Bug: Possible problem with KernelJsonSchema generation

2 participants