{"record":{"id":"658c9d628b9ee893","repo":"invoke-ai/InvokeAI","slug":"flux-ip-adapter-only-supports-a-single-image-promp","errorCode":null,"errorMessage":"FLUX IP-Adapter only supports a single image prompt (received {len(ipa_image_fields)}).","messagePattern":"FLUX IP-Adapter only supports a single image prompt \\(received (.+?)\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/flux_denoise.py","lineNumber":927,"sourceCode":"        device: torch.device,\n    ) -> tuple[list[torch.Tensor], list[torch.Tensor]]:\n        \"\"\"Run the IPAdapter CLIPVisionModel, returning image prompt embeddings.\"\"\"\n        clip_image_processor = CLIPImageProcessor()\n\n        pos_image_prompt_clip_embeds: list[torch.Tensor] = []\n        neg_image_prompt_clip_embeds: list[torch.Tensor] = []\n        for ip_adapter_field in ip_adapter_fields:\n            # `ip_adapter_field.image` could be a list or a single ImageField. Normalize to a list here.\n            ipa_image_fields: list[ImageField]\n            if isinstance(ip_adapter_field.image, ImageField):\n                ipa_image_fields = [ip_adapter_field.image]\n            elif isinstance(ip_adapter_field.image, list):\n                ipa_image_fields = ip_adapter_field.image\n            else:\n                raise ValueError(f\"Unsupported IP-Adapter image type: {type(ip_adapter_field.image)}\")\n\n            if len(ipa_image_fields) != 1:\n                raise ValueError(\n                    f\"FLUX IP-Adapter only supports a single image prompt (received {len(ipa_image_fields)}).\"\n                )\n\n            ipa_images = [context.images.get_pil(image.image_name, mode=\"RGB\") for image in ipa_image_fields]\n\n            pos_images: list[npt.NDArray[np.uint8]] = []\n            neg_images: list[npt.NDArray[np.uint8]] = []\n            for ipa_image in ipa_images:\n                assert ipa_image.mode == \"RGB\"\n                pos_image = np.array(ipa_image)\n                # We use a black image as the negative image prompt for parity with\n                # https://github.com/XLabs-AI/x-flux-comfyui/blob/45c834727dd2141aebc505ae4b01f193a8414e38/nodes.py#L592-L593\n                # An alternative scheme would be to apply zeros_like() after calling the clip_image_processor.\n                neg_image = np.zeros_like(pos_image)\n                pos_images.append(pos_image)\n                neg_images.append(neg_image)\n\n            with context.models.load(ip_adapter_field.image_encoder_model) as image_encoder_model:","sourceCodeStart":909,"sourceCodeEnd":945,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/flux_denoise.py#L909-L945","documentation":"The FLUX (XLabs) IP-Adapter implementation consumes exactly one image prompt per adapter. If the normalized image field list contains zero or multiple ImageFields, this ValueError is raised before embedding computation.","triggerScenarios":"Passing a list of 0 or >=2 images (or a list-valued image connection) to a FLUX IP-Adapter used with flux_denoise; batch image collections wired into a single IP-Adapter node.","commonSituations":"Reusing an SDXL/SD1.5 IP-Adapter workflow (which supports multiple images) with the FLUX denoise node; accidentally connecting an image collection output instead of a single image.","solutions":["Connect exactly one image to the IP-Adapter invocation.","For multiple image prompts, create multiple IP-Adapter invocations (one image each) and pass a list of IPAdapterFields.","If migrating from SDXL workflows, remove the extra images rather than reusing the same graph with FLUX."],"exampleFix":"// before: one IP-Adapter with image list [img1, img2]\n// after: two IP-Adapter invocations, each with a single image, both feeding flux_denoise.ip_adapter","handlingStrategy":"validation","validationCode":"imgs = ip_adapter_field.image if isinstance(ip_adapter_field.image, list) else [ip_adapter_field.image]\nif len(imgs) != 1:\n    raise ValueError(f\"FLUX IP-Adapter needs exactly 1 image, got {len(imgs)}\")","typeGuard":"def is_single_image(image) -> bool:\n    if isinstance(image, ImageField):\n        return True\n    return isinstance(image, list) and len(image) == 1 and isinstance(image[0], ImageField)","tryCatchPattern":"try:\n    result = flux_denoise.invoke(context)\nexcept ValueError as e:\n    if \"only supports a single image prompt\" in str(e):\n        log.error(\"Provide exactly one image per FLUX IP-Adapter node\")\n    else:\n        raise","preventionTips":["Use one IP-Adapter node per image prompt on FLUX.","Do not connect collection outputs (batch image lists) to a FLUX IP-Adapter image input.","Audit SDXL workflows before porting them to FLUX."],"tags":["python","valueerror","flux","ip-adapter","constraint"],"backgroundTag":"unsupported-argument-count","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}