Skip to content

fix(core): a JSON Schema array without items is untyped, not strings - #8264

Open
fei (feiiiiii5) wants to merge 1 commit into
microsoft:mainfrom
feiiiiii5:fix/json-to-pydantic-array-without-items
Open

fei (feiiiiii5) wants to merge 1 commit into
microsoft:mainfrom
feiiiiii5:fix/json-to-pydantic-array-without-items

Conversation

@feiiiiii5

Copy link
Copy Markdown

Why

_extract_field_type's array branch treated a missing items schema as "items are strings":

item_schema = value.get("items", {"type": "string"})

Two consequences, both wrong against JSON Schema:

  1. {"type": "array"} with no items imposes no constraint on element type, yet the generated model rejected integers with nums.0 Input should be a valid string [input_value=1].
  2. Pydantic's own serialization of List[Any] is {"items": {}, "type": "array"} — an empty items schema. That hit the same default ({} has no "type", so the code then did item_type = str in the inner fallback), so a schema produced by Pydantic itself came back un-validatable through schema_to_pydantic_model / json_to_pydantic_model and type: array payloads were refused with input_value=True for a boolean list.

Printed at 027ecf0a with autogen_core.__file__ resolving inside the checked-out tree:

[A array-no-items    ] VALIDATION REJECTED: nums.0 Input should be a valid string [input_value=1]
[B array-empty-items ] VALIDATION REJECTED: nums.0 Input should be a valid string [input_value=True]

What changed

item_schema = value.get("items", {}), and when the items schema carries no "type" the element type is now Any instead of str. A comment records why, since Any is the kind of default a later reader is tempted to "fix" back.

$ref items, inline-object items, explicit-but-unsupported type names (UnsupportedKeywordError) and the minItems/maxItems constraints are untouched — the two new tests include a constrained case specifically to pin that unique/length constraints survive the change.

Tests

Two cases appended to python/packages/autogen-core/tests/test_json_to_pydantic.py: an {"type":"array"} with no items accepting mixed element types, and a {"items": {}} array with minItems/uniqueItems still enforced.

cd python/packages/autogen-core, PYTHONPATH=src:

$ git checkout 027ecf0a379bcc1d09956d46d12d44a3ad9cee14 -- src/autogen_core/utils/_json_to_pydantic.py
$ git diff -- src/autogen_core/utils/_json_to_pydantic.py      # empty, so this run measures upstream code
$ python -m pytest tests/test_json_to_pydantic.py -q
2 failed, 75 passed
FAILED tests/test_json_to_pydantic.py::test_array_without_items_accepts_any_element_type
FAILED tests/test_json_to_pydantic.py::test_constrained_array_without_items_keeps_constraints

$ # fix restored
27 passed → 77 passed, 4 warnings in 0.28s

(Parent agent re-ran both sides independently rather than trusting the report; the head summary is 77 passed.)

Environment limits, stated plainly: pytest tests for the whole package is not collectable here (9 collection errors from [dev] extras that need uv sync), and mypy/pyright did not run for the same reason, so the CI type gates are pending rather than verified. ruff check/ruff format --check on the two files give identical results at base and head (1 pre-existing I001 in the upstream test file, which this diff does not touch), so no new lint findings come from this change.

Checklist

  • Docstrings have been added/updated. — no public docstring semantics changed; the only added text is an inline comment. Say the word if you want it in the class docstring too.
  • Documentation has been added/updated. — no documentation change needed: schema_to_pydantic_model's existing description already promises JSON Schema semantics that this restores.
  • Unit tests have been added/updated.
  • All automated checks passed. — pending on CI (fork first-time run).

Heads-up on process, not on the code: CONTRIBUTING.md says most contributions need the Microsoft CLA, so the CLA bot will ask the account owner here — that is not something an agent can satisfy. And README.md says AutoGen is in maintenance mode with contributions limited to bug fixes, security patches and docs, which is what this is.

The array branch of _extract_field_type defaulted a missing items schema to str, so {"type": "array"} rejected integers with "Input should be a valid string". An absent items means no constraint on element type per JSON Schema, and Pydantic itself emits {"items": {}} for List[Any], which also hit the str default. Fall back to Any in both cases while keeping minItems/maxItems constraints.
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.

1 participant