pydantic/pydantic · error · PydanticUserError
type-adapter-config-unused
type-adapter-config-unused
Error message
Cannot use `config` when the type is a BaseModel, dataclass or TypedDict. These types can have their own config and setting the config via the `config` parameter to TypeAdapter will not override it, thus the `config` you passed to TypeAdapter becomes meaningless, which is probably not what you want.
What it means
TypeAdapter accepts a config parameter, but only for types that don't carry their own config. _type_has_config returns True for BaseModel, pydantic dataclass, and TypedDict subclasses, which define config internally. Passing config for such a type would be silently ignored, so pydantic raises PydanticUserError code 'type-adapter-config-unused' instead.
Source
Thrown at pydantic/type_adapter.py:203
def __init__(
self,
type: Any,
*,
config: ConfigDict | None = ...,
_parent_depth: int = ...,
module: str | None = ...,
) -> None: ...
def __init__(
self,
type: Any,
*,
config: ConfigDict | None = None,
_parent_depth: int = 2,
module: str | None = None,
) -> None:
if _type_has_config(type) and config is not None:
raise PydanticUserError(
'Cannot use `config` when the type is a BaseModel, dataclass or TypedDict.'
' These types can have their own config and setting the config via the `config`'
' parameter to TypeAdapter will not override it, thus the `config` you passed to'
' TypeAdapter becomes meaningless, which is probably not what you want.',
code='type-adapter-config-unused',
)
self._type = type
self._config = config
self._parent_depth = _parent_depth
self.pydantic_complete = False
parent_frame = self._fetch_parent_frame()
if isinstance(type, types.FunctionType):
# Special case functions, which are *not* pushed to the `NsResolver` stack and without this special case
# would only have access to the parent namespace where the `TypeAdapter` was instantiated (if the function is defined
# in another module, we need to look at that module's globals).
if parent_frame is not None:View on GitHub (pinned to 2e5f0e2b42)
Solutions
- Set the config on the model itself: class MyModel(BaseModel): model_config = ConfigDict(strict=True).
- For plain/non-config types (e.g. int, list[str], a non-pydantic dataclass), the config parameter is valid.
- If you need different config without editing the model, create a subclass with the desired model_config and adapt that.
Example fix
# before
TypeAdapter(MyModel, config=ConfigDict(strict=True))
# after
class StrictModel(MyModel):
model_config = ConfigDict(strict=True)
TypeAdapter(StrictModel) Defensive patterns
Strategy: validation
Validate before calling
from pydantic._internal import _model_construction
from pydantic import BaseModel, TypeAdapter
def adapter_for(tp, config=None):
from pydantic.type_adapter import _type_has_config
if config is not None and _type_has_config(tp):
raise ValueError(f'{tp!r} carries its own config; set model_config on the type instead')
return TypeAdapter(tp, config=config) Type guard
from pydantic.type_adapter import _type_has_config
def type_accepts_adapter_config(tp) -> bool:
return not _type_has_config(tp) Prevention
- Set config on the model/dataclass/TypedDict itself, not on the TypeAdapter wrapping it.
- Only pass config to TypeAdapter for plain/non-config types.
- Create a subclass with the desired model_config if you need a different config without editing the original.
When it happens
Trigger: TypeAdapter(MyModel, config=ConfigDict(strict=True)) where MyModel subclasses BaseModel; TypeAdapter over a dataclass or TypedDict with a config kwarg.
Common situations: Trying to override a model's strict/coerce behavior at the adapter level; wrapping an existing model with extra validation config.
Related errors
- model-config-invalid-field-name
- config-both
- Config has no attribute {name!r}
- validate-by-alias-and-name-false
- Inconsistent hierarchy, no C3 MRO is possible
AI-assisted analysis of pydantic/pydantic@2e5f0e2b42 (2026-08-04).
Data as JSON: /data/errors/16ef1f82121c87e1.json.
Report an issue: GitHub.