Package: Microsoft.Extensions.AI.OpenAI 10.6.0
Summary
OpenAIClientExtensions.ToOpenAIFunctionParameters deserializes every tool's schema via element.Deserialize(OpenAIJsonContext.Default.ToolJson), and the internal ToolJson type declares:
[JsonPropertyName("additionalProperties")] public bool AdditionalProperties { get; set; }
JSON Schema permits additionalProperties to be either a boolean or a sub-schema object. Any tool whose schema uses the object form throws:
System.Text.Json.JsonException: The JSON value could not be converted to System.Boolean. Path: $.additionalProperties | LineNumber: 0 | BytePositionInLine: 261.
…aborting the request. This happens for every function tool regardless of strict mode — ToOpenAIFunctionParameters deserializes into ToolJson on both the strict-transformed and the raw-schema branch — and on both the Chat Completions (ToOpenAIChatTool) and Responses/Assistants tool-conversion paths.
Repro
Create an AIFunction whose JsonSchema is:
{ "type": "object", "properties": { "labels": { "type": "object" } }, "additionalProperties": { "type": "string" } }
…and pass it as a tool to an OpenAI IChatClient. The request build throws the JsonException above. This schema shape is common in OpenAPI/MCP-derived tools (e.g. map/dictionary parameters render additionalProperties as a sub-schema).
Expected
The object form of additionalProperties is accepted (handled or normalized), not a hard JsonException.
Suggested fix
Type ToolJson.AdditionalProperties so it tolerates both forms (e.g. JsonElement, or bool? with a converter), or normalize the schema before deserialization.
Workaround
Wrap the IChatClient in a DelegatingChatClient that recursively coerces object-valued additionalProperties to false in each tool's schema before it reaches the bridge.
Package:
Microsoft.Extensions.AI.OpenAI10.6.0Summary
OpenAIClientExtensions.ToOpenAIFunctionParametersdeserializes every tool's schema viaelement.Deserialize(OpenAIJsonContext.Default.ToolJson), and the internalToolJsontype declares:JSON Schema permits
additionalPropertiesto be either a boolean or a sub-schema object. Any tool whose schema uses the object form throws:…aborting the request. This happens for every function tool regardless of strict mode —
ToOpenAIFunctionParametersdeserializes intoToolJsonon both the strict-transformed and the raw-schema branch — and on both the Chat Completions (ToOpenAIChatTool) and Responses/Assistants tool-conversion paths.Repro
Create an
AIFunctionwhoseJsonSchemais:{ "type": "object", "properties": { "labels": { "type": "object" } }, "additionalProperties": { "type": "string" } }…and pass it as a tool to an OpenAI
IChatClient. The request build throws theJsonExceptionabove. This schema shape is common in OpenAPI/MCP-derived tools (e.g. map/dictionary parameters renderadditionalPropertiesas a sub-schema).Expected
The object form of
additionalPropertiesis accepted (handled or normalized), not a hardJsonException.Suggested fix
Type
ToolJson.AdditionalPropertiesso it tolerates both forms (e.g.JsonElement, orbool?with a converter), or normalize the schema before deserialization.Workaround
Wrap the
IChatClientin aDelegatingChatClientthat recursively coerces object-valuedadditionalPropertiestofalsein each tool's schema before it reaches the bridge.