Skip to content

Commit cdebce9

Browse files
fix: Always set additionalProperties=false for strict schema compliance
Fixes #2740 The `to_strict_json_schema` function now always sets `additionalProperties` to `false` for object types, as required by the OpenAI API for structured output. Previously, it only set this value when the key was missing, which caused issues with Pydantic models using `extra="allow"`. When Pydantic models use `ConfigDict(extra="allow")`, the generated schema includes `"additionalProperties": true`. However, the OpenAI API requires `"additionalProperties": false` for structured output to work correctly. Changes: - Modified `_ensure_strict_json_schema()` to unconditionally set `additionalProperties = false` for all object types - Added comprehensive test case `test_pydantic_extra_allow()` to verify the fix handles models with `extra="allow"` correctly This ensures API compliance while maintaining backward compatibility with existing code.
1 parent 6574bcd commit cdebce9

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/openai/lib/_pydantic.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ def _ensure_strict_json_schema(
4747
_ensure_strict_json_schema(definition_schema, path=(*path, "definitions", definition_name), root=root)
4848

4949
typ = json_schema.get("type")
50-
if typ == "object" and "additionalProperties" not in json_schema:
50+
if typ == "object":
51+
# Always set additionalProperties to False for strict schema compliance.
52+
# The OpenAI API requires additionalProperties=false for structured output,
53+
# even if Pydantic models use extra="allow" which sets it to True.
5154
json_schema["additionalProperties"] = False
5255

5356
# object types

tests/lib/test_pydantic.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,3 +409,28 @@ def test_nested_inline_ref_expansion() -> None:
409409
"additionalProperties": False,
410410
}
411411
)
412+
413+
414+
def test_pydantic_extra_allow() -> None:
415+
"""Test that models with extra='allow' correctly set additionalProperties to False.
416+
417+
Regression test for issue #2740.
418+
The OpenAI API requires additionalProperties=false for structured output,
419+
even when Pydantic models use extra="allow" which generates True by default.
420+
"""
421+
from pydantic import ConfigDict
422+
423+
class MyClassWithExtraAllow(BaseModel):
424+
model_config = ConfigDict(extra="allow")
425+
field: str = Field(description="A test field")
426+
427+
schema = to_strict_json_schema(MyClassWithExtraAllow)
428+
429+
# The schema must have additionalProperties set to False
430+
assert schema.get("additionalProperties") == False, \
431+
"additionalProperties must be False for API compliance, even with extra='allow'"
432+
433+
# Verify the rest of the schema is correct
434+
assert schema["type"] == "object"
435+
assert "field" in schema["properties"]
436+
assert schema["required"] == ["field"]

0 commit comments

Comments
 (0)