langchain-ai/langchain · error · TypeError
Expected a Pydantic model. Got {model}
Error message
Expected a Pydantic model. Got {model} What it means
Raised by `get_fields` in `langchain_core.utils.pydantic` when the argument is neither a pydantic v1 nor v2 `BaseModel` (class or instance). The utility introspects `.model_fields` (v2) or `__fields__` (v1); anything else — dataclasses, TypedDicts, plain classes, primitives — is rejected with `TypeError`. It typically surfaces indirectly when passing a non-pydantic schema object into LangChain APIs that expect a pydantic model.
Source
Thrown at libs/core/langchain_core/utils/pydantic.py:347
def get_fields(
model: type[BaseModel | BaseModelV1] | BaseModel | BaseModelV1,
) -> dict[str, FieldInfoV2] | dict[str, ModelField]:
"""Return the field names of a Pydantic model.
Args:
model: The Pydantic model or instance.
Raises:
TypeError: If the model is not a Pydantic model.
"""
if not isinstance(model, type):
model = type(model)
if issubclass(model, BaseModel):
return model.model_fields
if issubclass(model, BaseModelV1):
return model.__fields__
msg = f"Expected a Pydantic model. Got {model}" # type: ignore[unreachable]
raise TypeError(msg)
def model_json_schema(model: TypeBaseModel) -> dict[str, Any]:
"""Return the JSON schema of a Pydantic model class of either major version.
Dispatches to the correct method for Pydantic v1 (`schema`) or v2
(`model_json_schema`), so callers holding a `TypeBaseModel` don't have to
branch on the model's version themselves.
Args:
model: The Pydantic model class.
Raises:
TypeError: If the model is not a Pydantic model class.
"""
if issubclass(model, BaseModel):
return model.model_json_schema()
if issubclass(model, BaseModelV1):View on GitHub (pinned to e32fa9a52e)
Solutions
- Convert the argument to a pydantic model: decorate dataclasses with `pydantic.dataclasses.dataclass` won't help here — define a `BaseModel` subclass with the same fields.
- If using TypedDict, switch to a pydantic `BaseModel` (or use an API path that accepts JSON Schema directly).
- If the value may legitimately vary, branch on `isinstance(obj, BaseModel)` (and pydantic.v1 `BaseModel`) before calling.
Example fix
# before
from dataclasses import dataclass
@dataclass
class Args:
query: str
get_fields(Args) # TypeError: Expected a Pydantic model.
# after
from pydantic import BaseModel
class Args(BaseModel):
query: str
get_fields(Args) Defensive patterns
Strategy: type-guard
Validate before calling
from pydantic import BaseModel
from pydantic.v1 import BaseModel as BaseModelV1
def has_fields(obj: Any) -> bool:
cls = obj if isinstance(obj, type) else type(obj)
return issubclass(cls, (BaseModel, BaseModelV1)) Type guard
from pydantic import BaseModel
from pydantic.v1 import BaseModel as BaseModelV1
def is_pydantic_model(obj: Any) -> TypeGuard[type[BaseModel] | type[BaseModelV1]]:
cls = obj if isinstance(obj, type) else type(obj)
return issubclass(cls, (BaseModel, BaseModelV1)) Try / catch
try:
fields = get_fields(obj)
except TypeError:
fields = None # or convert obj to a BaseModel first Prevention
- Type tool/structured-output args as TypeBaseModel, not Any, so mypy catches misuse.
- Convert dataclass schemas to BaseModel subclasses at the boundary.
- In tests, use real pydantic models rather than duck-typed fakes.
When it happens
Trigger: Calling `get_fields(obj)` (directly or via APIs that derive field schemas from models, such as tool/structured-output argument parsing) with a dataclass, `TypedDict`, `NamedTuple`, or arbitrary class. Note the function first does `type(model)` on instances, so instances of valid models are fine; only non-model types fail.
Common situations: Migrating code from dataclass-based tools to pydantic-based ones; passing a `TypedDict` where LangChain expects `BaseModel` (e.g. `with_structured_output`, tool args); duck-typed fakes/mocks in tests that are not pydantic models; mixing pydantic v1/v2 where the object is actually an unrelated class.
Related errors
- Invalid args_schema: expected BaseModel or dict, got {args_s
- Either data or path must be provided
- Unable to get string for blob {self}
- Unable to get bytes for blob {self}
- Vectorstore should be either a VectorStore or a DocumentInde
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/8597d6cc5ace9e55.
Report an issue: GitHub.