invoke-ai/InvokeAI · error · ValueError

Model config dict 'format' field must be a string or Enum

Error message

Model config dict 'format' field must be a string or Enum

What it means

Same discriminator logic as error 1015 but for the 'format' field: it must be a string or Enum, else ValueError. The tag built from type/format/base (and variant for CLIP Embed) selects the concrete config class in the discriminated union.

Source

Thrown at invokeai/backend/model_manager/configs/base.py:177

        # 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 (
                type_ == ModelType.CLIPEmbed.value
                and format_ == ModelFormat.Diffusers.value
                and base_ == BaseModelType.Any.value
            ):
                if variant_ := v.get("variant"):
                    if isinstance(variant_, Enum):
                        variant_ = variant_.value

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Use the enum value string: {'format': ModelFormat.Diffusers.value} or {'format': 'diffusers'}.
  2. Pass the ModelFormat Enum member directly.
  3. Fix the importer/serializer to emit string enum values.

Example fix

// before
{'type': 'main', 'format': 0, 'base': 'sd-1'}
// after
{'type': 'main', 'format': ModelFormat.Diffusers.value, 'base': 'sd-1'}
Defensive patterns

Strategy: validation

Validate before calling

def normalize_format(v) -> str:
    return v.value if isinstance(v, Enum) else str(v)

Type guard

def is_valid_format(v: object) -> TypeGuard[str | Enum]:
    return isinstance(v, (str, Enum))

Try / catch

try:
    config = AnyModelConfig(**cfg)
except ValueError as e:
    if "'format' field must be a string or Enum" in str(e):
        cfg['format'] = cfg['format'].value if isinstance(cfg['format'], Enum) else str(cfg['format'])
        config = AnyModelConfig(**cfg)
    else:
        raise

Prevention

When it happens

Trigger: Constructing a model config from a dict where 'format' is an int, None-like object, or bytes instead of a str/Enum (e.g. {'type': 'main', 'format': 1, ...}).

Common situations: Configs deserialized from external tools or DB rows where ModelFormat was stored as a numeric code; YAML with numeric-looking format values; typos that turned the value into something unexpected.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/1b10993767696d84. Report an issue: GitHub.