Skip to content

fix(parse): handle tuple prefixItems and boolean items in transform_schema - #2065

Open
xgbtxy wants to merge 1 commit into
anthropics:mainfrom
xgbtxy:fix/transform-schema-tuple-prefix-items
Open

xgbtxy wants to merge 1 commit into
anthropics:mainfrom
xgbtxy:fix/transform-schema-tuple-prefix-items

Conversation

@xgbtxy

@xgbtxy xgbtxy commented Nov 15, 2026

Copy link
Copy Markdown

Fixes #2064.

What was wrong

transform_schema (src/anthropic/lib/_parse/_transform.py) had three issues on type: "array" schemas using JSON Schema Draft 2020-12 prefixItems, boolean items, or Draft-07 list items:

  1. Crash on boolean items (items: False / items: True) and Draft-07 list items:
    # Before: raised TypeError: 'bool' object is not a mapping
    transform_schema({
        "type": "array",
        "prefixItems": [{"type": "integer"}, {"type": "string"}],
        "items": False,
    })
  2. Unsatisfiable strict schema on open typed-tail tuples (prefixItems + dict items):
    For {"type": "array", "prefixItems": [{"type": "integer"}], "items": {"type": "string"}, "minItems": 2}, Draft 2020-12 applies items only to indices >= len(prefixItems). Previously, transform_schema emitted {"type": "array", "items": {"type": "string"}, "description": "{prefixItems: [{'type': 'integer'}], minItems: 2}"}, forcing index 0 to be a string and preventing valid [42, "ok"] outputs.
  3. Unconstrained array and unreferenced $defs on Pydantic tuple[Step, int]:
    Pydantic v2 emits {"type": "array", "prefixItems": [{"$ref": "#/$defs/Step"}, {"type": "integer"}], "minItems": 2, "maxItems": 2}. Previously, strict_schema omitted "items" altogether, leaving #/$defs/Step unreferenced in $defs:
    # After:
    # properties.pair -> {
    #   "type": "array",
    #   "title": "Pair",
    #   "items": {"anyOf": [{"$ref": "#/$defs/Step"}, {"type": "integer"}]},
    #   "description": "{maxItems: 2, prefixItems: [{'$ref': '#/$defs/Step'}, {'type': 'integer'}], minItems: 2}",
    # }

What changed

  • Added transform_tuple_items in src/anthropic/lib/_parse/_transform.py to lower closed tuples (items: False or maxItems <= len(prefixItems)) and open typed-tail tuples (prefixItems + dict items, as well as Draft-07 list items + additionalItems) into strict_schema["items"] (deduplicated single schema when homogeneous, {"anyOf": [...]} when heterogeneous), while keeping open untyped-tail tuples (prefixItems without items and without maxItems <= len(prefixItems), or items: True) unconstrained on items.
  • Preserved non-dict items (False/True or list) and prefixItems in leftover description hints instead of passing non-dict items to transform_schema.
  • Guarded minItems with not isinstance(min_items, bool) so True/False are not treated as 1/0.

Wire-level / compatibility notes

  • Standard homogeneous array schemas ({"type": "array", "items": {...}}) are unchanged on the wire.
  • Closed Pydantic / JSON Schema tuple arrays now emit a sound and complete "items" constraint ({"anyOf": [...]} or single schema) on the wire instead of omitting "items" or raising TypeError.

Verification

  • Added unit tests in tests/lib/_parse/test_transform.py covering closed Draft 2020-12 tuples (items: False), open typed-tail tuples (prefixItems + dict items), open untyped-tail tuples, Draft-07 tuple lists, standalone items: False, and Pydantic v2 tuple[Step, int] / tuple[int, int].
  • Verified with pytest -n0 tests/lib/_parse/ (40 passed), ruff check, ruff format --check, and pyright strict mode (0 errors, 0 warnings).

…chema

Lower closed Draft 2020-12 `prefixItems` tuples, open typed-tail tuples (`prefixItems` + dict `items`), and Draft-07 list `items` tuples into `strict_schema["items"]` while preserving positional constraints in `description`, and guard against boolean `items` (`False`/`True`) and `bool` `minItems` values so `transform_schema` does not raise `TypeError`.

Fixes anthropics#2064
Assisted-by: Google Antigravity
@xgbtxy
xgbtxy requested a review from a team as a code owner November 15, 2026 00:04
Copilot AI balanced review requested due to automatic review settings November 15, 2026 00:04

Copilot AI left a comment

Copy link
Copy Markdown

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 insufficient remaining quota. Try requesting a review at a lower effort level.

This branch has not been deployed

No deployments
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.

transform_schema crashes on boolean array items and drops/misconstrains tuple prefixItems

2 participants