invoke-ai/InvokeAI · error · ValueError
Model config dict 'type' field must be a string or Enum
Error message
Model config dict 'type' field must be a string or Enum
What it means
get_model_discriminator_value builds a pydantic discriminated-union tag from a config dict's 'type' field, which must be a string or an Enum. Any other type raises ValueError so pydantic can route to the correct model config class.
Source
Thrown at invokeai/backend/model_manager/configs/base.py:170
@staticmethod
def get_model_discriminator_value(v: Any) -> str:
"""Computes the discriminator value for a model config discriminated union."""
# This is called by pydantic during deserialization and serialization to determine which model the data
# represents. It can get either a dict (during deserialization) or an instance of a Config_Base subclass
# (during serialization).
#
# See: https://docs.pydantic.dev/latest/concepts/unions/#discriminated-unions-with-callable-discriminator
if isinstance(v, Config_Base):
# We have an instance of a ModelConfigBase subclass - use its tag directly.
return v.get_tag().tag
if isinstance(v, dict):
# We have a dict - attempt to compute a tag from its fields.
tag_strings: list[str] = []
if type_ := v.get("type"):
if isinstance(type_, Enum):
type_ = str(type_.value)
elif not isinstance(type_, str):
raise ValueError("Model config dict 'type' field must be a string or Enum")
tag_strings.append(type_)
if format_ := v.get("format"):
if isinstance(format_, Enum):
format_ = str(format_.value)
elif not isinstance(format_, str):
raise ValueError("Model config dict 'format' field must be a string or Enum")
tag_strings.append(format_)
if base_ := v.get("base"):
if isinstance(base_, Enum):
base_ = str(base_.value)
elif not isinstance(base_, str):
raise ValueError("Model config dict 'base' field must be a string or Enum")
tag_strings.append(base_)
# Special case: CLIP Embed models also need the variant to distinguish them.
if (View on GitHub (pinned to 0b6a024f2f)
Solutions
- Pass the enum value string: {'type': ModelType.Main.value} or simply {'type': 'main'}.
- Pass the Enum member itself (isinstance Enum is accepted and converted).
- Fix serialization upstream so enums are dumped with use_enum_values or as strings, not ints/bytes.
Example fix
// before
{'type': 3, 'format': 'diffusers', 'base': 'sd-1'}
// after
{'type': ModelType.Main.value, 'format': 'diffusers', 'base': BaseModelType.StableDiffusion1.value} Defensive patterns
Strategy: validation
Validate before calling
from enum import Enum
def valid_discriminator_field(v) -> bool:
return isinstance(v, (str, Enum)) Type guard
def is_str_or_enum(v: object) -> TypeGuard[str | Enum]:
return isinstance(v, (str, Enum)) Try / catch
try:
config = AnyModelConfig(**cfg)
except ValueError as e:
if "'type' field must be a string or Enum" in str(e):
cfg['type'] = cfg['type'].value if isinstance(cfg['type'], Enum) else str(cfg['type'])
config = AnyModelConfig(**cfg)
else:
raise Prevention
- Serialize model configs with model_dump(mode='json') / use_enum_values so enums become strings.
- Never pass raw enum integer codes from external tools into config dicts.
- Write a small normalizer that maps every discriminator field through .value before instantiation.
When it happens
Trigger: Instantiating a model config (ModelConfigBase or subclass) from a dict whose 'type' is an int, ModelType-typed wrapper, bytes, or other non-str/non-Enum value.
Common situations: Loading configs from JSON where enums were serialized as integers; hand-writing a config dict with the wrong type; passing a ModelType instance that is not an Enum (e.g. a plain dataclass).
Related errors
- Model config dict 'format' field must be a string or Enum
- Model config dict 'base' field must be a string or Enum
- source_url must be a string
- Model config dict 'variant' field must be a string or Enum
- CLIP Embed model config dict must include a 'variant' field
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/c5da4a56d4724900.
Report an issue: GitHub.