{"record":{"id":"3fc9b8b6eee33264","repo":"invoke-ai/InvokeAI","slug":"encoder-hid-dim-has-to-be-defined-when-encoder","errorCode":null,"errorMessage":"`encoder_hid_dim` has to be defined when `encoder_hid_dim_type` is set to {encoder_hid_dim_type}.","messagePattern":"`encoder_hid_dim` has to be defined when `encoder_hid_dim_type` is set to (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/util/hotfixes.py","lineNumber":205,"sourceCode":"        )\n\n        # time\n        time_embed_dim = block_out_channels[0] * 4\n        self.time_proj = Timesteps(block_out_channels[0], flip_sin_to_cos, freq_shift)\n        timestep_input_dim = block_out_channels[0]\n        self.time_embedding = TimestepEmbedding(\n            timestep_input_dim,\n            time_embed_dim,\n            act_fn=act_fn,\n        )\n\n        if encoder_hid_dim_type is None and encoder_hid_dim is not None:\n            encoder_hid_dim_type = \"text_proj\"\n            self.register_to_config(encoder_hid_dim_type=encoder_hid_dim_type)\n            logger.info(\"encoder_hid_dim_type defaults to 'text_proj' as `encoder_hid_dim` is defined.\")\n\n        if encoder_hid_dim is None and encoder_hid_dim_type is not None:\n            raise ValueError(\n                f\"`encoder_hid_dim` has to be defined when `encoder_hid_dim_type` is set to {encoder_hid_dim_type}.\"\n            )\n\n        if encoder_hid_dim_type == \"text_proj\":\n            self.encoder_hid_proj = nn.Linear(encoder_hid_dim, cross_attention_dim)\n        elif encoder_hid_dim_type == \"text_image_proj\":\n            # image_embed_dim DOESN'T have to be `cross_attention_dim`. To not clutter the __init__ too much\n            # they are set to `cross_attention_dim` here as this is exactly the required dimension ...\n            # for the currently only use\n            # case when `addition_embed_type == \"text_image_proj\"` (Kadinsky 2.1)`\n            self.encoder_hid_proj = TextImageProjection(\n                text_embed_dim=encoder_hid_dim,\n                image_embed_dim=cross_attention_dim,\n                cross_attention_dim=cross_attention_dim,\n            )\n\n        elif encoder_hid_dim_type is not None:\n            raise ValueError(","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/util/hotfixes.py#L187-L223","documentation":"The model's __init__ (a diffusers-compatible UNet/ControlNet constructor in hotfixes.py) allows `encoder_hid_dim_type` to be set (explicitly or defaulted from `encoder_hid_dim`), but requires the hidden dimension `encoder_hid_dim` to accompany it. If `encoder_hid_dim` is None while `encoder_hid_dim_type` is not None, the encoder projection layer (e.g. nn.Linear) cannot be constructed, so the library raises this ValueError immediately. It is a config-consistency guard, not a runtime failure.","triggerScenarios":"Calling the model constructor (or from_config/from_pretrained with a config dict) with `encoder_hid_dim_type='text_proj'` or `'text_image_proj'` while `encoder_hid_dim` is omitted/None. Also happens when a hand-edited config.json sets encoder_hid_dim_type but drops encoder_hid_dim, or when loading a checkpoint whose config was partially migrated between diffusers versions.","commonSituations":"Hand-writing UNet2DConditionModel/ControlNet kwargs for IP-Adapter or custom text-encoder setups; copying config from a different model class; diffusers version upgrades that renamed/relocated encoder_hid_dim defaults; JSON config edits where one of the paired keys was deleted.","solutions":["Add `encoder_hid_dim=<int>` (matching your text encoder hidden size, e.g. 768 or 1024) to the constructor/config alongside `encoder_hid_dim_type`.","If you do not need an encoder hid projection, remove `encoder_hid_dim_type` (set it to None) so the default path (`encoder_hid_proj = None`) is taken.","Load the model via its official `from_pretrained`/`from_config` with the original config.json instead of hand-constructing kwargs.","If migrating from an older diffusers checkpoint, diff the config against the reference model class defaults and restore the dropped `encoder_hid_dim` key."],"exampleFix":"// before\nmodel = ControlNetModel2_5(\n    encoder_hid_dim_type=\"text_proj\",\n    cross_attention_dim=1024,\n)\n// after\nmodel = ControlNetModel2_5(\n    encoder_hid_dim=1024,\n    encoder_hid_dim_type=\"text_proj\",\n    cross_attention_dim=1024,\n)","handlingStrategy":"validation","validationCode":"cfg = model_config  # dict of constructor kwargs\nif cfg.get(\"encoder_hid_dim_type\") is not None and cfg.get(\"encoder_hid_dim\") is None:\n    raise ValueError(\"encoder_hid_dim must be set whenever encoder_hid_dim_type is set\")","typeGuard":"def encoder_hid_ok(cfg: dict) -> bool:\n    return cfg.get(\"encoder_hid_dim_type\") is None or isinstance(cfg.get(\"encoder_hid_dim\"), int)","tryCatchPattern":"try:\n    model = ControlNetModel2_5(**cfg)\nexcept ValueError as e:\n    if \"encoder_hid_dim\" in str(e):\n        cfg[\"encoder_hid_dim\"] = text_encoder_hidden_size\n        model = ControlNetModel2_5(**cfg)\n    else:\n        raise","preventionTips":["Always set encoder_hid_dim together with encoder_hid_dim_type; they are a paired config.","Load models from their original config.json rather than hand-copying kwargs.","After diffusers upgrades, diff old vs new config keys for the model class.","Keep encoder_hid_dim equal to your text encoder's hidden size (768 for SD1.5, 1024 for SDXL)."],"tags":["config-validation","valueerror","diffusers","model-init"],"backgroundTag":"invalid-model-config","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}