Skip to content

typed_dict_schema JSON schema ignores extras_schema when extra_fields_behavior is set via config #12809

@dsfaccini

Description

@dsfaccini

source: pydantic/pydantic-ai#4138 (comment)

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

GenerateJsonSchema.typed_dict_schema() correctly uses extras_schema to produce typed additionalProperties when extra_behavior is set as a top-level field on the schema, but ignores it when extra_fields_behavior is set via the config dict — always producing additionalProperties: true instead of the typed schema.

This was partially addressed by #10785 / #12123, but only the top-level extra_behavior path was fixed. The config fallback path (the elif 'additionalProperties' not in json_schema branch at the bottom of typed_dict_schema) sets True without consulting extras_schema:

# pydantic/json_schema.py — GenerateJsonSchema.typed_dict_schema()
elif 'additionalProperties' not in json_schema:
    extra = schema.get('config', {a}).get('extra_fields_behavior')
    if extra == 'forbid':
        json_schema['additionalProperties'] = False
    elif extra == 'allow':
        json_schema['additionalProperties'] = True  # <-- ignores extras_schema

Example Code

from pydantic_core import core_schema
from pydantic.json_schema import GenerateJsonSchema

# Top-level extra_behavior — CORRECT
schema_top = core_schema.typed_dict_schema(
    fields={'x': core_schema.typed_dict_field(core_schema.int_schema())},
    extra_behavior='allow',
    extras_schema=core_schema.int_schema(),
)
result_top = GenerateJsonSchema().generate(schema_top)
print(result_top['additionalProperties'])
# {'type': 'integer'} ✓

# Config extra_fields_behavior — BUG
schema_cfg = core_schema.typed_dict_schema(
    fields={'x': core_schema.typed_dict_field(core_schema.int_schema())},
    config=core_schema.CoreConfig(extra_fields_behavior='allow'),
    extras_schema=core_schema.int_schema(),
)
result_cfg = GenerateJsonSchema().generate(schema_cfg)
print(result_cfg['additionalProperties'])
# True ✗ — should be {'type': 'integer'}

Python, Pydantic & OS Version

pydantic version: 2.12.5
        pydantic-core version: 2.33.2
                 python version: 3.13.3 (main, Apr  8 2025, 13:54:08) [Clang 16.0.0 (clang-1600.0.26.6)]
                       platform: macOS-15.5-arm64-arm-64bit-Mach-O

Metadata

Metadata

Assignees

Labels

bug V2Bug related to Pydantic V2

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions