The Fix
pip install pydantic==2.5.0
Based on closed pydantic/pydantic issue #8716 · PR/commit linked
@@ -27,7 +27,7 @@
from ._generate_schema import GenerateSchema
from ._generics import get_standard_typevars_map
-from ._mock_val_ser import set_dataclass_mock_validator
+from ._mock_val_ser import set_dataclass_mocks
from ._schema_generation_shared import CallbackGetCoreSchemaHandler
import logging
from typing import ForwardRef, Optional, List
from pydantic import BaseModel, RootModel, TypeAdapter, ConfigDict, create_model
PYC = ConfigDict(defer_build=True, arbitrary_types_allowed=True)
class A_(BaseModel):
model_config = PYC
a: str
class B_(BaseModel):
model_config = PYC
la: List[ForwardRef('__types["A"]')]
types = {"__types":{"A":A_, "B":B_}}
A_.model_rebuild(_types_namespace=types)
B_.model_rebuild(_types_namespace=types)
E = create_model("E", __base__=(RootModel[Optional[ForwardRef("__types['A']")]],), __module__="debugging")
E.model_rebuild(_types_namespace=types)
# edit - this is what I want to do with the TypeAdapter instead
# assert E.model_validate(None).root is None
# we fail here
try:
D = TypeAdapter(Optional[ForwardRef("__types['A']")], config=PYC)
except Exception as e:
logging.exception(e)
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
Option A — Upgrade to fixed release\npip install pydantic==2.5.0\nWhen NOT to use: Do not use TypeAdapter for models requiring deferred initialization without proper support.\n\n
Why This Fix Works in Production
- Trigger: import logging
- Mechanism: TypeAdapter's defer_build behavior was not functioning as intended due to missing support for delayed initialization
- Why the fix works: Fixes the behavior of `defer_build` with `TypeAdapter`, addressing issues with delayed initialization. (first fixed release: 2.5.0).
Why This Breaks in Prod
- Shows up under Python 3.10 in real deployments (not just unit tests).
- TypeAdapter's defer_build behavior was not functioning as intended due to missing support for delayed initialization
- Surfaces as: import logging
Proof / Evidence
- GitHub issue: #8716
- Fix PR: https://github.com/pydantic/pydantic/pull/7736
- First fixed release: 2.5.0
- Reproduced locally: No (not executed)
- Last verified: 2026-02-09
- Confidence: 0.85
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.37
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“I'd need TypeAdapter to behave "as models" basically as container for generics, which is not intended use”
“TypeAdapter was never meant to be a field of a model”
“@commonism, Thanks for reporting this”
“@commonism, Hmm. After thinking about this more - TypeAdapters don't have a model_rebuild method or close equivalent, so I'm curious what you expected to happen…”
Failure Signature (Search String)
- import logging
Error Message
Stack trace
Error Message
-------------
import logging
from typing import ForwardRef, Optional, List
from pydantic import BaseModel, RootModel, TypeAdapter, ConfigDict, create_model
PYC = ConfigDict(defer_build=True, arbitrary_types_allowed=True)
class A_(BaseModel):
model_config = PYC
a: str
class B_(BaseModel):
model_config = PYC
la: List[ForwardRef('__types["A"]')]
types = {"__types":{"A":A_, "B":B_}}
A_.model_rebuild(_types_namespace=types)
B_.model_rebuild(_types_namespace=types)
E = create_model("E", __base__=(RootModel[Optional[ForwardRef("__types['A']")]],), __module__="debugging")
E.model_rebuild(_types_namespace=types)
# edit - this is what I want to do with the TypeAdapter instead
# assert E.model_validate(None).root is None
# we fail here
try:
D = TypeAdapter(Optional[ForwardRef("__types['A']")], config=PYC)
except Exception as e:
logging.exception(e)
Minimal Reproduction
import logging
from typing import ForwardRef, Optional, List
from pydantic import BaseModel, RootModel, TypeAdapter, ConfigDict, create_model
PYC = ConfigDict(defer_build=True, arbitrary_types_allowed=True)
class A_(BaseModel):
model_config = PYC
a: str
class B_(BaseModel):
model_config = PYC
la: List[ForwardRef('__types["A"]')]
types = {"__types":{"A":A_, "B":B_}}
A_.model_rebuild(_types_namespace=types)
B_.model_rebuild(_types_namespace=types)
E = create_model("E", __base__=(RootModel[Optional[ForwardRef("__types['A']")]],), __module__="debugging")
E.model_rebuild(_types_namespace=types)
# edit - this is what I want to do with the TypeAdapter instead
# assert E.model_validate(None).root is None
# we fail here
try:
D = TypeAdapter(Optional[ForwardRef("__types['A']")], config=PYC)
except Exception as e:
logging.exception(e)
Environment
- Python: 3.10
- Pydantic: 2
What Broke
Users experienced failures when attempting to use TypeAdapter with deferred builds, leading to unexpected exceptions.
Why It Broke
TypeAdapter's defer_build behavior was not functioning as intended due to missing support for delayed initialization
Fix Options (Details)
Option A — Upgrade to fixed release Safe default (recommended)
pip install pydantic==2.5.0
Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.
Fix reference: https://github.com/pydantic/pydantic/pull/7736
First fixed release: 2.5.0
Last verified: 2026-02-09. Validate in your environment.
When NOT to Use This Fix
- Do not use TypeAdapter for models requiring deferred initialization without proper support.
Verify Fix
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
Did This Fix Work in Your Case?
Quick signal helps us prioritize which fixes to verify and improve.
Prevention
- Add a CI check that diffs key outputs after upgrades (OpenAPI schema snapshots, JSON payload shapes, CLI output).
- Upgrade behind a canary and run integration tests against the canary before 100% rollout.
Version Compatibility Table
| Version | Status |
|---|---|
| 2.5.0 | Fixed |
Related Issues
No related fixes found.
Sources
We don’t republish the full GitHub discussion text. Use the links above for context.