{"record":{"id":"788a195b6f6f1900","repo":"invoke-ai/InvokeAI","slug":"class-embed-type-projection-requires-project","errorCode":null,"errorMessage":"`class_embed_type`: 'projection' requires `projection_class_embeddings_input_dim` be set","messagePattern":"`class_embed_type`: 'projection' requires `projection_class_embeddings_input_dim` be set","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/util/hotfixes.py","lineNumber":238,"sourceCode":"            )\n\n        elif encoder_hid_dim_type is not None:\n            raise ValueError(\n                f\"encoder_hid_dim_type: {encoder_hid_dim_type} must be None, 'text_proj' or 'text_image_proj'.\"\n            )\n        else:\n            self.encoder_hid_proj = None\n\n        # class embedding\n        if class_embed_type is None and num_class_embeds is not None:\n            self.class_embedding = nn.Embedding(num_class_embeds, time_embed_dim)\n        elif class_embed_type == \"timestep\":\n            self.class_embedding = TimestepEmbedding(timestep_input_dim, time_embed_dim)\n        elif class_embed_type == \"identity\":\n            self.class_embedding = nn.Identity(time_embed_dim, time_embed_dim)\n        elif class_embed_type == \"projection\":\n            if projection_class_embeddings_input_dim is None:\n                raise ValueError(\n                    \"`class_embed_type`: 'projection' requires `projection_class_embeddings_input_dim` be set\"\n                )\n            # The projection `class_embed_type` is the same as the timestep `class_embed_type` except\n            # 1. the `class_labels` inputs are not first converted to sinusoidal embeddings\n            # 2. it projects from an arbitrary input dimension.\n            #\n            # Note that `TimestepEmbedding` is quite general, being mainly linear layers and activations.\n            # When used for embedding actual timesteps, the timesteps are first converted to sinusoidal embeddings.\n            # As a result, `TimestepEmbedding` can be passed arbitrary vectors.\n            self.class_embedding = TimestepEmbedding(projection_class_embeddings_input_dim, time_embed_dim)\n        else:\n            self.class_embedding = None\n\n        if addition_embed_type == \"text\":\n            if encoder_hid_dim is not None:\n                text_time_embedding_from_dim = encoder_hid_dim\n            else:\n                text_time_embedding_from_dim = cross_attention_dim","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/util/hotfixes.py#L220-L256","documentation":"When `class_embed_type='projection'`, the class-label embedding is a linear projection whose input size must be known, so `projection_class_embeddings_input_dim` is mandatory. The constructor raises this ValueError when the projection type is selected but the input dimension is missing, because TimestepEmbedding cannot be sized without it. Related: when this projection type is used, `addition_embed_type` must typically also be None, and adding_time_dims derive from this value.","triggerScenarios":"Constructing the model with `class_embed_type=\"projection\"` while `projection_class_embeddings_input_dim` is None/omitted — e.g. a partially copied SDXL-style config where the projection keys were dropped, or a config.json that sets class_embed_type without the accompanying dimension key.","commonSituations":"Adapting an SDXL/SSD-1B config onto a ControlNet/UNet class; truncating a config dict when copying only some keys; checkpoint configs authored for models that defaulted projection_class_embeddings_input_dim at a higher level (pipeline/scheduler config) instead of the model config.","solutions":["Set `projection_class_embeddings_input_dim` to the summed size of all conditioning embeddings (e.g. SDXL: 2816 = 4*281 timesteps + 768 text + 1280+... per model card).","If you don't need projection class embedding, change `class_embed_type` to None, 'timestep', or 'identity'.","Load with the original, complete config.json via from_pretrained instead of reconstructing kwargs manually.","Diff your constructor kwargs against the upstream reference config for the checkpoint you are loading."],"exampleFix":"// before\nmodel = ControlNetModel2_5(\n    class_embed_type=\"projection\",\n    addition_embed_type=\"text_time\",\n)\n// after\nmodel = ControlNetModel2_5(\n    class_embed_type=\"projection\",\n    addition_embed_type=\"text_time\",\n    projection_class_embeddings_input_dim=2816,\n)","handlingStrategy":"validation","validationCode":"if model_config.get(\"class_embed_type\") == \"projection\" and model_config.get(\"projection_class_embeddings_input_dim\") is None:\n    raise ValueError(\"class_embed_type='projection' needs projection_class_embeddings_input_dim\")","typeGuard":"def projection_config_complete(cfg: dict) -> bool:\n    if cfg.get(\"class_embed_type\") != \"projection\":\n        return True\n    return isinstance(cfg.get(\"projection_class_embeddings_input_dim\"), int)","tryCatchPattern":"try:\n    model = ControlNetModel2_5(**cfg)\nexcept ValueError as e:\n    if \"projection_class_embeddings_input_dim\" in str(e):\n        cfg[\"projection_class_embeddings_input_dim\"] = 2816  # SDXL default total cond dim\n        model = ControlNetModel2_5(**cfg)\n    else:\n        raise","preventionTips":["Copy the full key group (class_embed_type, projection_class_embeddings_input_dim, addition_embed_type, addition_time_embed_dim) as a unit from the reference config.","Compute the projection dim as the sum of all conditioning embedding widths for your base model.","Use from_pretrained with the shipped config.json instead of reconstructing model kwargs.","Sanity-check configs against upstream examples for SDXL-family checkpoints."],"tags":["config-validation","valueerror","sdxl","diffusers"],"backgroundTag":"invalid-model-config","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}