{"id":"da1c3c043629c4b4","repo":"pydantic/pydantic","slug":"model-config-invalid-field-name","errorCode":"model-config-invalid-field-name","errorMessage":"`model_config` cannot be used as a model field name. Use `model_config` for model configuration.","messagePattern":"`model_config` cannot be used as a model field name\\. Use `model_config` for model configuration\\.","errorType":"error_code","errorClass":"PydanticUserError","httpStatus":null,"severity":"error","filePath":"pydantic/_internal/_config.py","lineNumber":166,"sourceCode":"            bases: A tuple of base classes.\n            namespace: The namespace of the class being created.\n            raw_annotations: The (non-evaluated) annotations of the model.\n            kwargs: The kwargs passed to the class being created.\n\n        Returns:\n            A `ConfigWrapper` instance for `BaseModel`.\n        \"\"\"\n        config_new = ConfigDict()\n        for base in bases:\n            config = getattr(base, 'model_config', None)\n            if config:\n                config_new.update(config.copy())\n\n        config_class_from_namespace = namespace.get('Config')\n        config_dict_from_namespace = namespace.get('model_config')\n\n        if raw_annotations.get('model_config') and config_dict_from_namespace is None:\n            raise PydanticUserError(\n                '`model_config` cannot be used as a model field name. Use `model_config` for model configuration.',\n                code='model-config-invalid-field-name',\n            )\n\n        if config_class_from_namespace and config_dict_from_namespace:\n            raise PydanticUserError('\"Config\" and \"model_config\" cannot be used together', code='config-both')\n\n        config_from_namespace = config_dict_from_namespace or prepare_config(config_class_from_namespace)\n\n        config_new.update(config_from_namespace)\n\n        for k in list(kwargs.keys()):\n            if k in config_keys:\n                config_new[k] = kwargs.pop(k)\n\n        return cls(config_new)\n\n    # we don't show `__getattr__` to type checkers so missing attributes cause errors","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/pydantic/pydantic/blob/2e5f0e2b4218de31709f1cf9c5bc61ea97a68835/pydantic/_internal/_config.py#L148-L184","documentation":"In ConfigWrapper.for_model, Pydantic inspects the class namespace annotations. The name model_config is reserved for holding the ConfigDict that configures the model. If model_config appears only as a type annotation (raw_annotations.get('model_config') is truthy) but no actual model_config value is assigned in the namespace, Pydantic treats it as an attempt to declare a model field literally named model_config, which collides with the reserved configuration slot and is rejected with code model-config-invalid-field-name.","triggerScenarios":"Writing `class M(BaseModel): model_config: ConfigDict` (annotation only, no assignment), or `class M(BaseModel): model_config: str` treating it as a field, or annotating model_config without assigning a ConfigDict while intending a field. The check at _config.py:165-169 fires when raw_annotations has 'model_config' but namespace.get('model_config') is None.","commonSituations":"Migrating from V1 where developers wrote a Config inner class and accidentally leave a stray `model_config: ...` annotation; forgetting to assign the ConfigDict after annotating it (e.g., `model_config: ConfigDict` then never doing `model_config = ConfigDict(...)`).","solutions":["Assign model_config instead of merely annotating it: change `model_config: ConfigDict` to `model_config = ConfigDict(...)`.","If you intended a real field, rename it to something other than model_config (the name is reserved).","Remove the stray annotation if it was left over from a V1->V2 migration."],"exampleFix":"# before\nclass M(BaseModel):\n    model_config: ConfigDict  # annotation only -> error\n\n# after\nclass M(BaseModel):\n    model_config = ConfigDict(extra='forbid')","handlingStrategy":"validation","validationCode":"from typing import get_type_hints\nimport inspect\n\ndef ensure_model_config_assigned(cls):\n    anns = getattr(cls, '__annotations__', {})\n    if 'model_config' in anns and 'model_config' not in cls.__dict__:\n        raise TypeError('model_config is annotated but not assigned; use model_config = ConfigDict(...)')","typeGuard":"def is_valid_model_config(namespace: dict) -> bool:\n    return not (namespace.get('__annotations__', {}).get('model_config')\n                and namespace.get('model_config') is None)","tryCatchPattern":"try:\n    class M(BaseModel): ...\nexcept PydanticUserError as e:\n    if e.code == 'model-config-invalid-field-name':\n        # assign model_config = ConfigDict(...) instead of annotating\n        raise\n    raise","preventionTips":["Always assign model_config with =, never only annotate it.","After V1->V2 migration, grep for stray `model_config:` annotations.","Reserve the name model_config exclusively for configuration."],"tags":["python","pydantic","config","model-config","v2-migration","reserved-name"],"analyzedSha":"2e5f0e2b4218de31709f1cf9c5bc61ea97a68835","analyzedAt":"2026-08-04T19:54:21.281Z","schemaVersion":2}