Comfy-Org/ComfyUI · error · ValueError

The number of controls is not equal to the number of skip co

Error message

The number of controls is not equal to the number of skip connections.

What it means

After the U-Net-style skip pass over HYDiT blocks, if ControlNet outputs remain unconsumed the counts did not line up: each control output is popped and added to one skip connection in the decoder half, and leftovers mean the ControlNet depth does not match the DiT depth.

Source

Thrown at comfy/ldm/hydit/models.py:392

            else:
                skip = None

            if ("double_block", layer) in blocks_replace:
                def block_wrap(args):
                    out = {}
                    out["img"] = block(args["img"], args["vec"], args["txt"], args["pe"], args["skip"])
                    return out

                out = blocks_replace[("double_block", layer)]({"img": x, "txt": text_states, "vec": c, "pe": freqs_cis_img, "skip": skip}, {"original_block": block_wrap})
                x = out["img"]
            else:
                x = block(x, c, text_states, freqs_cis_img, skip)   # (N, L, D)


            if layer < (self.depth // 2 - 1):
                skips.append(x)
        if controls is not None and len(controls) != 0:
            raise ValueError("The number of controls is not equal to the number of skip connections.")

        # ========================= Final layer =========================
        x = self.final_layer(x, c)                              # (N, L, patch_size ** 2 * out_channels)
        x = self.unpatchify(x, th, tw)                          # (N, out_channels, H, W)

        if return_dict:
            return {'x': x}
        if self.learn_sigma:
            return x[:,:self.out_channels // 2,:oh,:ow]
        return x[:,:,:oh,:ow]

    def unpatchify(self, x, h, w):
        """
        x: (N, T, patch_size**2 * C)
        imgs: (N, H, W, C)
        """
        c = self.unpatchify_channels
        p = self.x_embedder.patch_size[0]

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Use a ControlNet checkpoint that matches the loaded DiT's depth (number of control outputs <= depth//2 - 1 and fully consumed)
  2. Verify the DiT config depth and the controlnet's output count from its state dict before applying
  3. Update to the matching DiT checkpoint version the ControlNet was trained against
Defensive patterns

Strategy: validation

Validate before calling

n_control = len(control['output'])
n_skips = model.depth // 2 - 1
assert n_control <= n_skips, f"controlnet too deep: {n_control} > {n_skips}"

Prevention

When it happens

Trigger: Attaching a ControlNet whose 'output' list is longer than depth//2 - 1 skip connections (e.g. a 40-layer controlnet on a shallower DiT), or a depth/config mismatch between the controlnet checkpoint and the loaded DiT.

Common situations: Loading a ControlNet trained for HunYuanDiT v1.x onto a different-sized DiT (different depth), or applying a control signal computed for another model version.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/4e43767650b352ed. Report an issue: GitHub.