{"record":{"id":"dad093fcc483c61b","repo":"invoke-ai/InvokeAI","slug":"invalid-class-name-from-config-actual-class-name","errorCode":null,"errorMessage":"invalid class name from config: {actual_class_name}","messagePattern":"invalid class name from config: (.+?)","errorType":"validation","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/identification_utils.py","lineNumber":129,"sourceCode":"    return config_class_name\n\n\ndef raise_for_class_name(config: Path | set[Path] | dict[str, Any], class_name: str | set[str]) -> None:\n    \"\"\"Get the class name from the config file and raise NotAMatch if it is not in the expected set.\n\n    Args:\n        config_path: The path to the config file, or a set of paths to try.\n        class_name: The expected class name, or a set of expected class names.\n\n    Raises:\n        NotAMatch if the class name is not in the expected set.\n    \"\"\"\n\n    class_name = {class_name} if isinstance(class_name, str) else class_name\n\n    actual_class_name = get_class_name_from_config_dict_or_raise(config)\n    if actual_class_name not in class_name:\n        raise NotAMatchError(f\"invalid class name from config: {actual_class_name}\")\n\n\ndef raise_for_override_fields(candidate_config_class: type[BaseModel], override_fields: dict[str, Any]) -> None:\n    \"\"\"Check if the provided override fields are valid for the config class using pydantic.\n\n    For example, if the candidate config class has a field \"base\" of type Literal[BaseModelType.StableDiffusion1], and\n    the override fields contain \"base\": BaseModelType.Flux, this function will raise NotAMatch.\n\n    Internally, this function extracts the pydantic schema for each individual override field from the candidate config\n    class and validates the override value against that schema. Post-instantiation validators are not run.\n\n    Args:\n        candidate_config_class: The config class that is being tested.\n        override_fields: The override fields provided by the user.\n\n    Raises:\n        NotAMatch if any override field is invalid for the config class.\n    \"\"\"","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/identification_utils.py#L111-L147","documentation":"raise_for_class_name extracts the class name from the model's config dict and checks membership in the expected class_name set. If the config's `_class_name`/`architectures` value is not among the expected names, it raises NotAMatchError. This is how InvokeAI rejects models whose pipeline class differs from the config class being probed.","triggerScenarios":"Calling from_model_on_disk for a specific config class (e.g. _validate_looks_like_flux_diffusers, _validate_looks_like_z_image_diffusers, _validate_looks_like_flux2_diffusers) when the model's config declares a different _class_name/architectures than the class being tried.","commonSituations":"Pointing a model folder at the wrong config record; diffusers updated the pipeline class name between versions (e.g. renamed pipelines); a model variant (e.g. a LoRA or unrelated pipeline) stored in a directory expected to hold a different architecture.","solutions":["Open the model's config.json / model_index.json and read the actual _class_name value.","Register the model under the InvokeAI config class matching that actual class name instead of the one you tried.","If the class name changed across library versions, update the InvokeAI model config records or InvokeAI itself to a version that knows the new name.","Move the model to the correct directory/type so the right probe matches."],"exampleFix":"// before: probing a model whose config says _class_name: \"Flux2Pipeline\" with the Flux1 validator\nraise_for_class_name(config, \"FluxPipeline\")\n// after\nraise_for_class_name(config, {\"FluxPipeline\", \"Flux2Pipeline\"})  # or use the matching config class","handlingStrategy":"validation","validationCode":"import json, pathlib\nactual = json.loads(pathlib.Path(path, \"model_index.json\").read_text()).get(\"_class_name\")\nassert actual in EXPECTED_CLASS_NAMES, f\"model is {actual}, expected one of {EXPECTED_CLASS_NAMES}\"","typeGuard":"def has_expected_class_name(cfg: dict, expected: set[str]) -> bool:\n    name = cfg.get(\"_class_name\")\n    return isinstance(name, str) and name in expected","tryCatchPattern":"try:\n    record = from_model_on_disk(mod)\nexcept NotAMatchError as e:\n    if \"invalid class name\" in str(e):\n        logger.info(\"model class does not match any candidate config: %s\", e)","preventionTips":["Match the registered config record to the pipeline class actually declared in model_index.json","Watch for pipeline class renames across diffusers versions","Keep model directories organized by architecture"],"tags":["model-config","class-mismatch","invokeai"],"backgroundTag":"class-name-mismatch","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}