-
Notifications
You must be signed in to change notification settings - Fork 4.4k
fix: Always set additionalProperties=false for strict schema compliance #2743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: Always set additionalProperties=false for strict schema compliance #2743
Conversation
Fixes openai#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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preserve schemas for typed dictionaries when enforcing strictness
Overwriting additionalProperties unconditionally means any object schema that intentionally defines a value schema for dynamic keys (e.g. Pydantic fields of type Dict[str, T]) now loses that schema and becomes additionalProperties: False. These dict fields previously produced {"additionalProperties": {…}} so the model could accept arbitrary keys whose values match the inner schema; after this change the generated schema forbids all keys, so structured outputs containing mappings can never validate even though the underlying model allows them. Consider only forcing False when the value is a boolean and leaving structured additionalProperties schemas intact.
Useful? React with 👍 / 👎.
| # Verify the rest of the schema is correct | ||
| assert schema["type"] == "object" | ||
| assert "field" in schema["properties"] | ||
| assert schema["required"] == ["field"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use inline snapshots here
Summary
Fixes #2740
This PR resolves an issue where Pydantic models using
ConfigDict(extra="allow")fail when used with structured output becauseadditionalPropertiesis not forced tofalse.Problem
The OpenAI API requires
"additionalProperties": falsein JSON schemas for structured output (response_format). When Pydantic models useextra="allow", the generated schema includes"additionalProperties": true, which causes the API to reject the request with:Root Cause
The
_ensure_strict_json_schema()function (line 50) only setadditionalProperties = falsewhen the key was not already present:This conditional approach failed for Pydantic models with
extra="allow"because those models already have"additionalProperties": truein their schema.Solution
Modified the code to always set
additionalProperties = falsefor object types, regardless of whether the key already exists:Changes
src/openai/lib/_pydantic.py: Updated_ensure_strict_json_schema()to unconditionally setadditionalProperties = falsetest_pydantic_extra_allow()intests/lib/test_pydantic.pyto verify the fixTesting
Manual Testing
Reproduced the issue from #2740 and verified the fix resolves it:
Before fix:
After fix:
Test Coverage
Added comprehensive test that verifies:
extra="allow"correctly generateadditionalProperties: falseBackward Compatibility
This change is backward compatible:
extra="allow"already hadadditionalProperties: falseextra="allow"now work correctly (previously failed)References
extra="allow"#2740