Comfy-Org/ComfyUI · error · ValueError

y is None, did you try using a controlnet for SDXL on SD1?

Error message

y is None, did you try using a controlnet for SDXL on SD1?

What it means

When a ControlNet was trained with class embeddings (num_classes is not None, typical for SDXL ControlNets that consume the 'y' conditioning vector), forward requires y at sampling time. SD1/SD2 pipelines do not produce this vector, so passing an SDXL controlnet against an SD1 checkpoint leaves y as None and raises ValueError immediately.

Source

Thrown at comfy/cldm/cldm.py:417

                    "Please consider using the ProMax ControlNet Union model.\n" +
                    "https://huggingface.co/xinsir/controlnet-union-sdxl-1.0/tree/main"
                )

            emb += self.control_add_embedding(control_type, emb.dtype, emb.device)
            if len(control_type) > 0:
                if len(hint.shape) < 5:
                    hint = hint.unsqueeze(dim=0)
                guided_hint = self.union_controlnet_merge(hint, control_type, emb, context)

        if guided_hint is None:
            guided_hint = self.input_hint_block(hint, emb, context)

        out_output = []
        out_middle = []

        if self.num_classes is not None:
            if y is None:
                raise ValueError("y is None, did you try using a controlnet for SDXL on SD1?")
            emb = emb + self.label_emb(y)

        h = x
        for module, zero_conv in zip(self.input_blocks, self.zero_convs):
            if guided_hint is not None:
                h = module(h, emb, context)
                h += guided_hint
                guided_hint = None
            else:
                h = module(h, emb, context)
            out_output.append(zero_conv(h, emb, context))

        h = self.middle_block(h, emb, context)
        out_middle.append(self.middle_block_out(h, emb, context))

        return {"middle": out_middle, "output": out_output}

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Match checkpoints: use the SDXL checkpoint with the SDXL controlnet, or swap in an SD1-compatible controlnet.
  2. Check the controlnet's config/num_classes and the base model family before connecting nodes.
  3. If the controlnet genuinely supports both, ensure your sampler/model patch path passes y (c_concat/adv conditioning) into forward.
Defensive patterns

Strategy: validation

Validate before calling

if controlnet.num_classes is not None and y is None:
    raise SystemExit("SDXL controlnet requires SDXL base model / y conditioning")

Type guard

def controlnet_matches_base(controlnet, y) -> bool:
    return controlnet.num_classes is None or y is not None

Try / catch

try:
    controlnet(x_noisy, hint, timesteps, context, y=y)
except ValueError as e:
    if "y is None" in str(e):
        raise SystemExit("Swap in an SD1 controlnet or use the SDXL base model")
    raise

Prevention

When it happens

Trigger: Loading an SDXL ControlNet (e.g. sdxl-controlnet with label embedding) into a workflow whose UNet is SD1.x; mixing models where the controlnet expects adv_cond 'y' but the model sampler never supplies it.

Common situations: Wrong controlnet dropped into an SD1.5 workflow; using diffusers-style SDXL controlnets without wiring the extra conditioning; model folder mix-ups after a re-download.

Related errors


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