pydantic/pydantic · error · ValueError
"RootModel.__init__" accepts either a single positional argu
Error message
"RootModel.__init__" accepts either a single positional argument or arbitrary keyword arguments
What it means
RootModel.__init__ takes either a single positional `root` argument OR arbitrary keyword arguments (which become the root dict). Passing BOTH a positional root and keyword data is ambiguous, so ValueError is raised. When kwargs are given, root must be unset.
Source
Thrown at pydantic/root_model.py:66
__pydantic_root_model__ = True
__pydantic_private__ = None
__pydantic_extra__ = None
root: RootModelRootType
def __init_subclass__(cls, **kwargs):
extra = cls.model_config.get('extra')
if extra is not None:
raise PydanticUserError(
"`RootModel` does not support setting `model_config['extra']`", code='root-model-extra'
)
super().__init_subclass__(**kwargs)
def __init__(self, /, root: RootModelRootType = PydanticUndefined, **data) -> None: # type: ignore
__tracebackhide__ = True
if data:
if root is not PydanticUndefined:
raise ValueError(
'"RootModel.__init__" accepts either a single positional argument or arbitrary keyword arguments'
)
root = data # type: ignore
self.__pydantic_validator__.validate_python(root, self_instance=self)
__init__.__pydantic_base_init__ = True # pyright: ignore[reportFunctionMemberAccess]
@classmethod
def model_construct(cls, root: RootModelRootType, _fields_set: set[str] | None = None) -> Self: # type: ignore
"""Create a new model using the provided root object and update fields set.
Args:
root: The root object of the model.
_fields_set: The set of fields to be updated.
Returns:
The new model.
View on GitHub (pinned to 2e5f0e2b42)
Solutions
- Pass either positional root OR keyword arguments, not both.
- For dict-root models, build the dict first then pass it positionally: MyRoot({'a': 1}).
- Adjust generic factory code to choose one form based on the model kind.
Example fix
# before
m = MyRoot({'a': 1}, b=2)
# after
m = MyRoot({'a': 1, 'b': 2})
# or
m = MyRoot(a=1, b=2) Defensive patterns
Strategy: validation
Validate before calling
def build_root_model(cls, root=..., **kwargs):
if root is not ... and kwargs:
raise ValueError('pass either positional root or kwargs, not both')
return cls(root) if root is not ... else cls(**kwargs) Type guard
def root_init_args_valid(root_provided: bool, has_kwargs: bool) -> bool:
return not (root_provided and has_kwargs) Try / catch
try:
m = MyRoot(data, **extra)
except ValueError as e:
if 'RootModel.__init__' in str(e):
m = MyRoot({**data, **extra}) # merge and retry Prevention
- Pass either positional root or keyword args to RootModel, never both.
- For dict-root models, merge into one dict before constructing.
- Audit generic factory code that forwards both *args and **kwargs.
When it happens
Trigger: MyRoot({'a': 1}, b=2); instantiating a RootModel[dict] with both a mapping positionally and keyword fields; generic factory code that always passes a dict plus kwargs.
Common situations: Programmatic construction that forwards both *args and **kwargs; migrating a BaseModel call site to a RootModel.
Related errors
- Unexpected field with name {ann_name!r}; only 'root' is allo
- To define root models, use `pydantic.RootModel` rather than
- root-model-extra
- {ROOT_KEY} cannot be mixed with other fields
- Field {discriminator_key!r} is not the same for all submodel
AI-assisted analysis of pydantic/pydantic@2e5f0e2b42 (2026-08-04).
Data as JSON: /data/errors/b989d356bb8a8835.json.
Report an issue: GitHub.