invoke-ai/InvokeAI · error · ValueError

unknown `controlnet_conditioning_channel_order`: {channel_or

Error message

unknown `controlnet_conditioning_channel_order`: {channel_order}

What it means

The patched ControlNetModel.forward (in InvokeAI's hotfixes) only accepts controlnet_conditioning_channel_order of 'rgb' or 'bgr'. Any other string reaches this final else and raises. The order controls whether the conditioning image is channel-flipped before use.

Source

Thrown at invokeai/backend/util/hotfixes.py:632

                you remove all prompts. A `guidance_scale` between 3.0 and 5.0 is recommended.
            return_dict (`bool`, defaults to `True`):
                Whether or not to return a [`~models.controlnet.ControlNetOutput`] instead of a plain tuple.

        Returns:
            [`~models.controlnet.ControlNetOutput`] **or** `tuple`:
                If `return_dict` is `True`, a [`~models.controlnet.ControlNetOutput`] is returned, otherwise a tuple is
                returned where the first element is the sample tensor.
        """
        # check channel order
        channel_order = self.config.controlnet_conditioning_channel_order

        if channel_order == "rgb":
            # in rgb order by default
            ...
        elif channel_order == "bgr":
            controlnet_cond = torch.flip(controlnet_cond, dims=[1])
        else:
            raise ValueError(f"unknown `controlnet_conditioning_channel_order`: {channel_order}")

        # prepare attention_mask
        if attention_mask is not None:
            attention_mask = (1 - attention_mask.to(sample.dtype)) * -10000.0
            attention_mask = attention_mask.unsqueeze(1)

        # convert encoder_attention_mask to a bias the same way we do for attention_mask
        if encoder_attention_mask is not None:
            encoder_attention_mask = (1 - encoder_attention_mask.to(sample.dtype)) * -10000.0
            encoder_attention_mask = encoder_attention_mask.unsqueeze(1)

        # 1. time
        timesteps = timestep
        if not torch.is_tensor(timesteps):
            # TODO: this requires sync between CPU and GPU. So try to pass timesteps as tensors if you can
            # This would be a good case for the `match` statement (Python 3.10+)
            is_mps = sample.device.type == "mps"
            if isinstance(timestep, float):

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Set controlnet_conditioning_channel_order to exactly "rgb" or "bgr" (lowercase)
  2. Omit the argument entirely to use the default rgb order
  3. Check the caller that forwards kwargs to ControlNet forward for a mis-serialized value

Example fix

// before
controlnet(..., controlnet_conditioning_channel_order="RGB")
// after
controlnet(..., controlnet_conditioning_channel_order="rgb")
Defensive patterns

Strategy: validation

Validate before calling

VALID_ORDERS = {"rgb", "bgr"}
if channel_order is not None and channel_order not in VALID_ORDERS:
    channel_order = "rgb"

Type guard

def is_valid_channel_order(v):
    return v in ("rgb", "bgr")

Try / catch

try:
    out = controlnet(..., controlnet_conditioning_channel_order=order)
except ValueError as e:
    logger.error("bad channel_order %r: %s", order, e)
    raise

Prevention

When it happens

Trigger: Calling ControlNet forward (directly or via a pipeline) with controlnet_conditioning_channel_order set to something other than "rgb" or "bgr", e.g. None, "RGB" (case-sensitive), or a typo like "bgrx".

Common situations: Typos or wrong casing in pipeline kwargs; porting code from another library that uses different naming; loading a config whose channel_order field was edited by hand.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/050191741498cec3. Report an issue: GitHub.