invoke-ai/InvokeAI · error · ValueError
Unsupported IP-Adapter image type
Error message
Unsupported IP-Adapter image type: {type(ip_adapter_field.image)} What it means
After normalizing, each IPAdapterField.image must be an ImageField or a list of ImageFields. FLUX IP-Adapter (XLabs) requires exactly one CLIP image prompt, so any other type (None, string, PIL image, etc.) raises this ValueError instead of failing later inside the model.
Solutions
- Ensure the IP-Adapter invocation's image input is connected to a Load Image invocation so image is a proper ImageField.
- If constructing IPAdapterField in code, pass ImageField(image_name=..., image_type=...), not a string or PIL object.
- Re-export/re-save the workflow with the current InvokeAI schema to migrate stale field values.
Example fix
// before field = IPAdapterField(ip_adapter_model=..., image="my-image.png", weight=1.0) // after from invokeai.app.invocations.primitives import ImageField field = IPAdapterField(ip_adapter_model=..., image=ImageField(image_name="my-image.png", image_type="results"), weight=1.0)
Defensive patterns
Strategy: validation
Validate before calling
img = ip_adapter_field.image assert isinstance(img, ImageField) or (isinstance(img, list) and all(isinstance(i, ImageField) for i in img)), "image must be ImageField or list[ImageField]"
Type guard
def is_valid_ipa_image(image) -> bool:
if isinstance(image, ImageField):
return True
return isinstance(image, list) and all(isinstance(i, ImageField) for i in image) Try / catch
try:
result = flux_denoise.invoke(context)
except ValueError as e:
if "Unsupported IP-Adapter image type" in str(e):
log.error("IPAdapterField.image must be an ImageField, not %s", type(ip_adapter_field.image))
else:
raise Prevention
- Always connect a Load Image node to the IP-Adapter image input.
- Never pass raw image-name strings when constructing IPAdapterField in scripts.
- Re-save old workflows under the current schema before reuse.
When it happens
Trigger: An IPAdapterField whose image attribute holds something other than ImageField/list[ImageField] — typically a hand-constructed field, a migrated graph with a missing image connection, or a custom node populating image with a string image name.
Common situations: Custom scripts building IPAdapterField programmatically and passing the image name string instead of an ImageField; workflows imported from older schema versions where the image reference was not upgraded.
Related errors
- FLUX IP-Adapter only supports a single image prompt
- IP-Adapter masks are not yet supported in Flux.
- Unsupported IP-Adapter type
- LoRA model is in unsupported FLUX format
- Unknown lora: !
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/d695d7fb8391b662.
Report an issue: GitHub.
Appendix: source
Thrown at invokeai/app/invocations/flux_denoise.py:924
self,
ip_adapter_fields: list[IPAdapterField],
context: InvocationContext,
device: torch.device,
) -> tuple[list[torch.Tensor], list[torch.Tensor]]:
"""Run the IPAdapter CLIPVisionModel, returning image prompt embeddings."""
clip_image_processor = CLIPImageProcessor()
pos_image_prompt_clip_embeds: list[torch.Tensor] = []
neg_image_prompt_clip_embeds: list[torch.Tensor] = []
for ip_adapter_field in ip_adapter_fields:
# `ip_adapter_field.image` could be a list or a single ImageField. Normalize to a list here.
ipa_image_fields: list[ImageField]
if isinstance(ip_adapter_field.image, ImageField):
ipa_image_fields = [ip_adapter_field.image]
elif isinstance(ip_adapter_field.image, list):
ipa_image_fields = ip_adapter_field.image
else:
raise ValueError(f"Unsupported IP-Adapter image type: {type(ip_adapter_field.image)}")
if len(ipa_image_fields) != 1:
raise ValueError(
f"FLUX IP-Adapter only supports a single image prompt (received {len(ipa_image_fields)})."
)
ipa_images = [context.images.get_pil(image.image_name, mode="RGB") for image in ipa_image_fields]
pos_images: list[npt.NDArray[np.uint8]] = []
neg_images: list[npt.NDArray[np.uint8]] = []
for ipa_image in ipa_images:
assert ipa_image.mode == "RGB"
pos_image = np.array(ipa_image)
# We use a black image as the negative image prompt for parity with
# https://github.com/XLabs-AI/x-flux-comfyui/blob/45c834727dd2141aebc505ae4b01f193a8414e38/nodes.py#L592-L593
# An alternative scheme would be to apply zeros_like() after calling the clip_image_processor.
neg_image = np.zeros_like(pos_image)
pos_images.append(pos_image)View on GitHub (pinned to 0b6a024f2f)