{"record":{"id":"38852a7d24c9bdc4","repo":"invoke-ai/InvokeAI","slug":"must-provide-the-same-number-of-only-cross-attent","errorCode":null,"errorMessage":"Must provide the same number of `only_cross_attention` as `down_block_types`. `only_cross_attention`: {only_cross_attention}. `down_block_types`: {down_block_types}.","messagePattern":"Must provide the same number of `only_cross_attention` as `down_block_types`\\. `only_cross_attention`: (.+?)\\. `down_block_types`: (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/util/hotfixes.py","lineNumber":168,"sourceCode":"        # If `num_attention_heads` is not defined (which is the case for most models)\n        # it will default to `attention_head_dim`. This looks weird upon first reading it and it is.\n        # The reason for this behavior is to correct for incorrectly named variables that were introduced\n        # when this library was created...\n        # The incorrect naming was only discovered much ...\n        # later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131\n        # Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking\n        # which is why we correct for the naming here.\n        num_attention_heads = num_attention_heads or attention_head_dim\n\n        # Check inputs\n        if len(block_out_channels) != len(down_block_types):\n            raise ValueError(\n                f\"Must provide the same number of `block_out_channels` as `down_block_types`. \\\n                    `block_out_channels`: {block_out_channels}. `down_block_types`: {down_block_types}.\"\n            )\n\n        if not isinstance(only_cross_attention, bool) and len(only_cross_attention) != len(down_block_types):\n            raise ValueError(\n                f\"Must provide the same number of `only_cross_attention` as `down_block_types`. \\\n                    `only_cross_attention`: {only_cross_attention}. `down_block_types`: {down_block_types}.\"\n            )\n\n        if not isinstance(num_attention_heads, int) and len(num_attention_heads) != len(down_block_types):\n            raise ValueError(\n                f\"Must provide the same number of `num_attention_heads` as `down_block_types`. \\\n                    `num_attention_heads`: {num_attention_heads}. `down_block_types`: {down_block_types}.\"\n            )\n\n        if isinstance(transformer_layers_per_block, int):\n            transformer_layers_per_block = [transformer_layers_per_block] * len(down_block_types)\n\n        # input\n        conv_in_kernel = 3\n        conv_in_padding = (conv_in_kernel - 1) // 2\n        self.conv_in = nn.Conv2d(\n            in_channels, block_out_channels[0], kernel_size=conv_in_kernel, padding=conv_in_padding","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/util/hotfixes.py#L150-L186","documentation":"The same hotfixed ControlNetModel.__init__ validates only_cross_attention: unless it is a single bool applied to all blocks, it must be a tuple/list whose length equals down_block_types. If it is a non-bool sequence of the wrong length, per-block attention routing is undefined, so a ValueError is raised.","triggerScenarios":"Passing only_cross_attention=(True, False) (length 2) to a 4-block ControlNetModel; passing a list produced by slicing or per-block logic that doesn't match the down_block_types length.","commonSituations":"Migrating configs between models of different block counts; generating only_cross_attention programmatically from a different-length list; typos in hand-edited config.json where a bool was expanded to a partial list.","solutions":["Pass a single bool (e.g. only_cross_attention=False) if the same value applies to all blocks.","Otherwise provide exactly one boolean per down block: len(only_cross_attention) == len(down_block_types).","Derive it programmatically: only_cross_attention = [False] * len(down_block_types).","Compare against the reference model's config.json and copy the field verbatim."],"exampleFix":"// before\nControlNetModel(\n    down_block_types=(\"CrossAttnDownBlock2D\", \"CrossAttnDownBlock2D\", \"DownBlock2D\", \"DownBlock2D\"),\n    only_cross_attention=(True, False),\n)\n// after\nControlNetModel(\n    down_block_types=(\"CrossAttnDownBlock2D\", \"CrossAttnDownBlock2D\", \"DownBlock2D\", \"DownBlock2D\"),\n    only_cross_attention=(True, False, False, False),\n)","handlingStrategy":"validation","validationCode":"def validate_only_cross_attention(config: dict) -> None:\n    oca = config.get('only_cross_attention', False)\n    n = len(config['down_block_types'])\n    if not isinstance(oca, bool) and len(oca) != n:\n        raise ValueError(\n            f'only_cross_attention ({len(oca)}) must match down_block_types ({n})'\n        )\n\nvalidate_only_cross_attention(config_dict)","typeGuard":"def only_cross_attention_is_valid(config: dict) -> bool:\n    oca = config.get('only_cross_attention', False)\n    if isinstance(oca, bool):\n        return True\n    return isinstance(oca, (list, tuple)) and len(oca) == len(config.get('down_block_types', []))","tryCatchPattern":"try:\n    model = ControlNetModel.from_config(config_dict)\nexcept ValueError as e:\n    if 'only_cross_attention' in str(e):\n        config_dict['only_cross_attention'] = False  # uniform value applies to all blocks\n        model = ControlNetModel.from_config(config_dict)\n    else:\n        raise","preventionTips":["Prefer a single bool for only_cross_attention unless per-block control is truly needed.","Derive per-block lists with [x] * len(down_block_types) rather than hand-writing them.","Validate tuple lengths against down_block_types in a shared config-checking utility.","Copy attention-related fields verbatim from the source model's config.json."],"tags":["config-validation","diffusers","controlnet","model-config"],"backgroundTag":"config-list-length-mismatch","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}