From cdebce941252c8817447108b395b90997d45ec40 Mon Sep 17 00:00:00 2001 From: Yashwant Bezawada Date: Sun, 9 Nov 2025 03:12:07 -0600 Subject: [PATCH] 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. --- src/openai/lib/_pydantic.py | 5 ++++- tests/lib/test_pydantic.py | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/openai/lib/_pydantic.py b/src/openai/lib/_pydantic.py index 3cfe224cb1..02bd2bcdf0 100644 --- a/src/openai/lib/_pydantic.py +++ b/src/openai/lib/_pydantic.py @@ -47,7 +47,10 @@ def _ensure_strict_json_schema( _ensure_strict_json_schema(definition_schema, path=(*path, "definitions", definition_name), root=root) typ = json_schema.get("type") - if typ == "object" and "additionalProperties" not in json_schema: + if typ == "object": + # Always set additionalProperties to False for strict schema compliance. + # The OpenAI API requires additionalProperties=false for structured output, + # even if Pydantic models use extra="allow" which sets it to True. json_schema["additionalProperties"] = False # object types diff --git a/tests/lib/test_pydantic.py b/tests/lib/test_pydantic.py index 754a15151c..43006ac37c 100644 --- a/tests/lib/test_pydantic.py +++ b/tests/lib/test_pydantic.py @@ -409,3 +409,28 @@ def test_nested_inline_ref_expansion() -> None: "additionalProperties": False, } ) + + +def test_pydantic_extra_allow() -> None: + """Test that models with extra='allow' correctly set additionalProperties to False. + + Regression test for issue #2740. + The OpenAI API requires additionalProperties=false for structured output, + even when Pydantic models use extra="allow" which generates True by default. + """ + from pydantic import ConfigDict + + class MyClassWithExtraAllow(BaseModel): + model_config = ConfigDict(extra="allow") + field: str = Field(description="A test field") + + schema = to_strict_json_schema(MyClassWithExtraAllow) + + # The schema must have additionalProperties set to False + assert schema.get("additionalProperties") == False, \ + "additionalProperties must be False for API compliance, even with extra='allow'" + + # Verify the rest of the schema is correct + assert schema["type"] == "object" + assert "field" in schema["properties"] + assert schema["required"] == ["field"]