{"record":{"id":"51f0f6c67d91f35d","repo":"invoke-ai/InvokeAI","slug":"model-config-dict-variant-field-must-be-a-string","errorCode":null,"errorMessage":"Model config dict 'variant' field must be a string or Enum","messagePattern":"Model config dict 'variant' field must be a string or Enum","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/base.py","lineNumber":197,"sourceCode":"\n            if base_ := v.get(\"base\"):\n                if isinstance(base_, Enum):\n                    base_ = str(base_.value)\n                elif not isinstance(base_, str):\n                    raise ValueError(\"Model config dict 'base' field must be a string or Enum\")\n                tag_strings.append(base_)\n\n            # Special case: CLIP Embed models also need the variant to distinguish them.\n            if (\n                type_ == ModelType.CLIPEmbed.value\n                and format_ == ModelFormat.Diffusers.value\n                and base_ == BaseModelType.Any.value\n            ):\n                if variant_ := v.get(\"variant\"):\n                    if isinstance(variant_, Enum):\n                        variant_ = variant_.value\n                    elif not isinstance(variant_, str):\n                        raise ValueError(\"Model config dict 'variant' field must be a string or Enum\")\n                    tag_strings.append(variant_)\n                else:\n                    raise ValueError(\"CLIP Embed model config dict must include a 'variant' field\")\n\n            return \".\".join(tag_strings)\n        else:\n            raise ValueError(\n                \"Model config discriminator value must be computed from a dict or ModelConfigBase instance\"\n            )\n\n    @classmethod\n    @abstractmethod\n    def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:\n        \"\"\"Given the model on disk and any override fields, attempt to construct an instance of this config class.\n\n        This method serves to identify whether the model on disk matches this config class, and if so, to extract any\n        additional metadata needed to instantiate the config.\n","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/base.py#L179-L215","documentation":"For CLIP Embed models (type=clip_embed, format=diffusers, base=any), the discriminator also requires a 'variant' string/Enum field; a non-str/non-Enum variant raises ValueError during discriminator computation.","triggerScenarios":"Creating a CLIP Embed config dict where 'variant' is present but is an int, bytes, or other object - e.g. {'type': 'clip_embed', 'format': 'diffusers', 'base': 'any', 'variant': 1}.","commonSituations":"Serialized CLIP Vision configs from older InvokeAI versions where variant was stored numerically; scripts generating configs with unconverted enum codes.","solutions":["Pass a string variant (or CLIPVisionModelVariant Enum member), e.g. 'large' / CLIPVisionModelVariant.LARGE.","Fix the deserializer to convert variant enums with .value.","Drop the field only if this is not actually a CLIP Embed model - check type/format/base."],"exampleFix":"// before\n{'type': 'clip_embed', 'format': 'diffusers', 'base': 'any', 'variant': 1}\n// after\n{'type': 'clip_embed', 'format': 'diffusers', 'base': 'any', 'variant': CLIPVisionModelVariant.LARGE.value}","handlingStrategy":"validation","validationCode":"def normalize_variant(v) -> str:\n    return v.value if isinstance(v, Enum) else str(v)","typeGuard":"def is_valid_variant(v: object) -> TypeGuard[str | Enum]:\n    return isinstance(v, (str, Enum))","tryCatchPattern":"try:\n    config = AnyModelConfig(**cfg)\nexcept ValueError as e:\n    if \"'variant' field must be a string or Enum\" in str(e):\n        cfg['variant'] = cfg['variant'].value if isinstance(cfg['variant'], Enum) else str(cfg['variant'])\n        config = AnyModelConfig(**cfg)\n    else:\n        raise","preventionTips":["For CLIP Embed models always set variant from CLIPVisionModelVariant.","Serialize enums with .value when exporting configs between versions/tools.","Add regression tests for clip_embed config construction."],"tags":["invokeai","pydantic","discriminator","clip-embed"],"backgroundTag":"discriminator-validation-failed","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}