Skip to content

fix(python): map type(None) to null in kernel JSON schema builder - #14493

Open
Aniket Kumar (aniketkrs) wants to merge 1 commit into
microsoft:mainfrom
aniketkrs:fix/schema-null-type
Open

Aniket Kumar (aniketkrs) wants to merge 1 commit into
microsoft:mainfrom
aniketkrs:fix/schema-null-type

Conversation

@aniketkrs

Copy link
Copy Markdown

Fixes #14482

User-facing impact: Agent tool schemas for parameters typed with multi-member unions like int | str | None emitted anyOf: [integer, string, object] — the None branch became type object instead of null. Models receiving the wrong schema can emit {} where null/omission was intended, and downstream function-calling payloads break.

Technical cause: TYPE_MAPPING in python/semantic_kernel/schema/kernel_json_schema_builder.py has no entry for type(None), and both get_json_schema and build_from_type_name default unknown lookups to "object". Only the 2-arg Optional[T] path is special-cased (into {"type": [T, "null"]}); for 3+ member unions, each arg goes through cls.build(...) → get_json_schema(type(None)) → {"type": "object"}.

Fix: Add one entry to TYPE_MAPPING: type(None): "null". Now build(int | str | None) produces {"anyOf": [{"type": "integer"}, {"type": "string"}, {"type": "null"}]}, and dict[str, None] value schemas also improve from object to null.

The Optional[T] path is unaffected (it never consults TYPE_MAPPING for None), and the existing tests in python/tests/unit/schema/test_schema_builder.py only assert the 2-arg form, so no behavior change for them.

Copilot AI lite review requested due to automatic review settings September 27, 2026 04:04
@aniketkrs
Aniket Kumar (aniketkrs) requested a review from a team as a code owner September 27, 2026 04:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Community review, so this does not clear the merge gate.

I read the diff (one line in python/semantic_kernel/schema/kernel_json_schema_builder.py) and tested it in a local venv with semantic_kernel installed, by patching TYPE_MAPPING at runtime. I did not run the repo test suite.

Confirmed the bug on an unpatched install: KernelJsonSchemaBuilder.build(int | str | None) returns {'anyOf': [{'type': 'integer'}, {'type': 'string'}, {'type': 'object'}]}. The None branch is wrong. Optional[int] is fine ({'type': ['integer', 'null']}), as the description says.

With TYPE_MAPPING[type(None)] = "null" applied:

  • build(int | str | None) gives anyOf with integer, string and null. Correct.
  • build(list[int | None]) still gives items: {'type': ['integer', 'null']}. Unchanged and fine.
  • build(type(None)) gives {'type': 'null'}.

Two things to raise:

  1. The description says dict[str, None] value schemas also improve from object to null. I did not see that. Before and after the change I got {'type': 'object', 'additionalProperties': {'type': 'object', 'properties': {}}}. So that claim looks wrong for this input, or it needs a different input than the one I used. Please either drop the claim or add a test that shows it.
  2. The string path is not covered. build_from_type_name looks up type-name strings, and "None" is not a key, so it still maps to object. I did not check whether _parse_parameter can ever hand a "None" string to the builder, because it skips NoneType args when it builds type_, so this may be unreachable for decorated functions.

There is no test in the PR. A one-case test in tests/unit/schema/test_schema_builder.py asserting the int | str | None anyOf would lock the behavior in and take two minutes.

The fix is right for the main case. I would ask for a test and a corrected description.

This branch had an error being deployed

1 failed deployment
github-app-auth — ab914208 Deployed Sep 27, 2026 by aniketkrs via review #545
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.Net: [Python] KernelJsonSchemaBuilder maps None to JSON "object" in multi-member unions

3 participants