invoke-ai/InvokeAI · error · ValueError

A ControlNet VAE is required when using an InstantX FLUX Con

Error message

A ControlNet VAE is required when using an InstantX FLUX ControlNet.

What it means

InstantX FLUX ControlNets apply their conditioning by encoding the control image through a VAE. The invocation requires that VAE to be supplied via the controlnet_vae field; when the loaded ControlNet is an InstantXControlNetFlux and controlnet_vae is None, it raises instead of proceeding without conditioning.

Source

Thrown at invokeai/app/invocations/flux_denoise.py:748

        # TODO(ryand): Add a field to the model config so that we can distinguish between XLabs and InstantX ControlNets
        # before loading the models. Then make sure that all VAE encoding is done before loading the ControlNets to
        # minimize peak memory.

        # Calculate the controlnet conditioning tensors.
        # We do this before loading the ControlNet models because it may require running the VAE, and we are trying to
        # keep peak memory down.
        controlnet_conds: list[torch.Tensor] = []
        for controlnet in controlnets:
            image = context.images.get_pil(controlnet.image.image_name)

            # HACK(ryand): We have to load the ControlNet model to determine whether the VAE needs to be run. We really
            # shouldn't have to load the model here. There's a risk that the model will be dropped from the model cache
            # before we load it into VRAM and thus we'll have to load it again (context:
            # https://github.com/invoke-ai/InvokeAI/issues/7513).
            controlnet_model = context.models.load(controlnet.control_model)
            if isinstance(controlnet_model.model, InstantXControlNetFlux):
                if self.controlnet_vae is None:
                    raise ValueError("A ControlNet VAE is required when using an InstantX FLUX ControlNet.")
                vae_info = context.models.load(self.controlnet_vae.vae)
                controlnet_conds.append(
                    InstantXControlNetExtension.prepare_controlnet_cond(
                        controlnet_image=image,
                        vae_info=vae_info,
                        latent_height=latent_height,
                        latent_width=latent_width,
                        dtype=dtype,
                        device=device,
                        resize_mode=controlnet.resize_mode,
                    )
                )
            elif isinstance(controlnet_model.model, XLabsControlNetFlux):
                controlnet_conds.append(
                    XLabsControlNetExtension.prepare_controlnet_cond(
                        controlnet_image=image,
                        latent_height=latent_height,
                        latent_width=latent_width,

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Connect a FLUX-compatible VAE to the controlnet_vae field of the FLUX Denoise invocation.
  2. Switch to an XLabs FLUX ControlNet model if a VAE input is not desired (XLabs variants don't require it).
  3. Verify the workflow's VAE loader feeds the denoise node before running the graph.

Example fix

// before
denoise.control = instantXControlNetField; // controlnet_vae unset
// after
denoise.control = instantXControlNetField;
denoise.controlnet_vae = vaeField; // required for InstantX ControlNets
Defensive patterns

Strategy: validation

Validate before calling

if denoise.control is not None and denoise.controlnet_vae is None:
    # InstantX FLUX ControlNets require a VAE
    raise ValueError('controlnet_vae is required for InstantX FLUX ControlNets')

Type guard

def instantx_control_ready(denoise) -> bool:
    return denoise.control is None or denoise.controlnet_vae is not None

Try / catch

try:
    result = invoke(denoise)
except ValueError as e:
    if 'ControlNet VAE is required' in str(e):
        denoise.controlnet_vae = load_flux_vae()
        result = invoke(denoise)
    else:
        raise

Prevention

When it happens

Trigger: Using a FLUX ControlNet model that resolves to InstantXControlNetFlux while leaving controlnet_vae unset on the FLUX Denoise invocation; the check occurs per-ControlNet in _prep_controlnet_extensions after loading the ControlNet model.

Common situations: Selecting an InstantX ControlNet (e.g. InstantX Canny/Depth for FLUX) in a workflow built for XLabs ControlNets, which don't need the VAE field; forgetting the VAE connection when switching ControlNet models.

Related errors


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