Skip to content
Notifications
Clear all

How do I stop it from 'fixing' my Pydantic models into invalid JSON schemas?

3 Posts
2 Users
0 Reactions
25 Views
(@gracehopper2)
Reputable Member
Joined: 3 months ago
Posts: 388
Topic starter   [#20008]

I keep running into a frustrating pattern when I ask for help with Pydantic model configuration. I’ll share a model that uses a `Union` type or a `Literal`, and the assistant will confidently suggest I add `json_schema_extra` or use `model_config` to "fix" the schema. The problem is, the suggested config often makes the generated JSON Schema *invalid* according to the OpenAPI spec.

Here's a recent example. I had this simple model:

```python
from pydantic import BaseModel
from typing import Union, Literal

class Event(BaseModel):
event_type: Literal["login", "logout"]
details: Union[str, dict[str, str]]
```

I asked: "How can I make the JSON Schema for this model use `oneOf` for the union field?" A common assistant response was to override the schema, but it went off the rails:

**The Suggested (Problematic) Output:**
It recommended adding a `model_config` like:

```python
model_config = {
"json_schema_extra": {
"properties": {
"details": {
"oneOf": [
{"type": "string"},
{"type": "object", "additionalProperties": {"type": "string"}}
]
}
}
}
}
```

**Why This Fails:**
This `json_schema_extra` completely *replaces* the schema for the `details` property. It not only duplicates Pydantic's correct automatic `oneOf` generation, but it also **omits the `"title"` key** that Pydantic automatically adds from the field name. More critically, the suggested `additionalProperties` structure is often malformed, and it breaks the integration with tools like FastAPI's OpenAPI docs because the schema becomes a disjoint mix of generated and manual overrides.

**The Correct Approach:**
Pydantic v2 handles this beautifully by default. For precise control, you should use `Field` with `json_schema_extra` on the specific field, not the whole model, to *augment* the schema, not replace it. Or, use `Union` types properly and let Pydantic do its job. The fix was simply to remove the manual config.

Has anyone else hit this? It feels like the assistant has memorized the "use `json_schema_extra`" pattern but doesn't understand how it interacts with Pydantic's internal schema generation, leading to invalid schemas. What other Pydantic "fixes" have backfired for you?

gh2


ship early, test often


   
Quote
(@elenag)
Reputable Member
Joined: 2 months ago
Posts: 337
 

Oh, that specific example is so revealing! It's like the assistant saw a union and jumped straight to manually overriding `properties`, but it completely missed that `oneOf` should be a peer to `type`, not nested inside it. The generated schema would fail validation because the structure is wrong.

This keeps happening because Pydantic's own schema generation for unions has improved a lot recently. For your model, using `Union[str, dict[str, str]]` with Pydantic V2 should already produce a valid `oneOf` in the JSON Schema. The "fix" often overwrites the correct, automated logic with a broken manual one.

Have you tried just letting Pydantic handle it? You might not need any extra config at all. Sometimes the best solution is to remove the "helpful" overrides.


test everything twice


   
ReplyQuote
(@elenag)
Reputable Member
Joined: 2 months ago
Posts: 337
 

You're spot on about letting Pydantic V2 handle it! I had a similar "aha" moment when I realized I was fighting the framework. My caveat would be around Literal types, though. Sometimes, if you have a very specific union where one branch is a Literal and another is a dict, I've seen the auto-generated schema get a bit verbose compared to a hand-tuned one for documentation clarity. But you're right, it's always *valid*, which is the most important thing. The hand-coded "fix" often breaks that fundamental validity for a minor formatting gain.


test everything twice


   
ReplyQuote