invoke-ai/InvokeAI · error · ValueError
Unsupported controlnet type: {type(self.control)}
Error message
Unsupported controlnet type: {type(self.control)} What it means
The control field of FLUX Denoise must be either None, a single FluxControlNetField, or a list of FluxControlNetFields. Any other object type on self.control cannot be interpreted as ControlNet input, so _prep_controlnet_extensions raises with the actual type.
Source
Thrown at invokeai/app/invocations/flux_denoise.py:728
def _prep_controlnet_extensions(
self,
context: InvocationContext,
exit_stack: ExitStack,
latent_height: int,
latent_width: int,
dtype: torch.dtype,
device: torch.device,
) -> list[XLabsControlNetExtension | InstantXControlNetExtension]:
# Normalize the controlnet input to list[ControlField].
controlnets: list[FluxControlNetField]
if self.control is None:
controlnets = []
elif isinstance(self.control, FluxControlNetField):
controlnets = [self.control]
elif isinstance(self.control, list):
controlnets = self.control
else:
raise ValueError(f"Unsupported controlnet type: {type(self.control)}")
# 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):View on GitHub (pinned to 0b6a024f2f)
Solutions
- Wrap the ControlNet model reference in a FluxControlNetField (output of a FLUX ControlNet loader node) and connect that.
- Pass None (or omit) instead of an empty/mismatched value when no ControlNet is needed.
- Pass a list of FluxControlNetField items for multiple ControlNets.
Example fix
// before denoise.control = rawImageField; // wrong type // after denoise.control = new FluxControlNetField(controlModel, image, controlWeight);
Defensive patterns
Strategy: type-guard
Validate before calling
if denoise.control is not None and not isinstance(denoise.control, (FluxControlNetField, list)):
raise ValueError('control must be FluxControlNetField or list of them') Type guard
def is_valid_control(v) -> bool:
if v is None:
return True
if isinstance(v, FluxControlNetField):
return True
return isinstance(v, list) and all(isinstance(x, FluxControlNetField) for x in v) Try / catch
try:
result = invoke(denoise)
except ValueError as e:
if 'Unsupported controlnet type' in str(e):
denoise.control = None # drop invalid control input
result = invoke(denoise)
else:
raise Prevention
- Only connect FLUX ControlNet loader node outputs to the control field
- Validate field types when building graphs programmatically
- Use a list field for multiple ControlNets instead of ad-hoc structures
When it happens
Trigger: Assigning an arbitrary object, wrong field type, or an incompatible node output to the control field of the FLUX Denoise invocation; a list containing mixed types is accepted by the isinstance(self.control, list) branch but a non-field scalar/dict is not.
Common situations: Wiring a non-ControlNet image field directly into control; version changes where the field type was renamed; programmatic graph building assigning a raw dict instead of a FluxControlNetField.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- Unsupported control_lllite type: {type(control_lllite)}
- Unsupported cfg_scale type: {type(cfg_scale)}
- Expected PreTrainedModel for Gemma encoder, got {type(gemma_
- Expected PreTrainedTokenizerBase for Gemma tokenizer, got {t
- Expected PidNet for PiD decoder, got {type(pid_net).__name__
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/f4502e995f684576.
Report an issue: GitHub.