{"record":{"id":"d695d7fb8391b662","repo":"invoke-ai/InvokeAI","slug":"unsupported-ip-adapter-image-type-type-ip-adapte","errorCode":null,"errorMessage":"Unsupported IP-Adapter image type: {type(ip_adapter_field.image)}","messagePattern":"Unsupported IP-Adapter image type: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/flux_denoise.py","lineNumber":924,"sourceCode":"        self,\n        ip_adapter_fields: list[IPAdapterField],\n        context: InvocationContext,\n        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)","sourceCodeStart":906,"sourceCodeEnd":942,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/flux_denoise.py#L906-L942","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nfield = IPAdapterField(ip_adapter_model=..., image=\"my-image.png\", weight=1.0)\n// after\nfrom invokeai.app.invocations.primitives import ImageField\nfield = IPAdapterField(ip_adapter_model=..., image=ImageField(image_name=\"my-image.png\", image_type=\"results\"), weight=1.0)","handlingStrategy":"validation","validationCode":"img = ip_adapter_field.image\nassert isinstance(img, ImageField) or (isinstance(img, list) and all(isinstance(i, ImageField) for i in img)), \"image must be ImageField or list[ImageField]\"","typeGuard":"def is_valid_ipa_image(image) -> bool:\n    if isinstance(image, ImageField):\n        return True\n    return isinstance(image, list) and all(isinstance(i, ImageField) for i in image)","tryCatchPattern":"try:\n    result = flux_denoise.invoke(context)\nexcept ValueError as e:\n    if \"Unsupported IP-Adapter image type\" in str(e):\n        log.error(\"IPAdapterField.image must be an ImageField, not %s\", type(ip_adapter_field.image))\n    else:\n        raise","preventionTips":["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."],"tags":["python","valueerror","flux","ip-adapter","image-field"],"backgroundTag":"unsupported-argument-type","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}