{"record":{"id":"588884d2253db064","repo":"invoke-ai/InvokeAI","slug":"source-image-required-for-inpaint-mask-when-inpain-588884","errorCode":null,"errorMessage":"Source image required for inpaint mask when inpaint model used!","messagePattern":"Source image required for inpaint mask when inpaint model used!","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/stable_diffusion/extensions/inpaint_model.py","lineNumber":39,"sourceCode":"        self,\n        mask: Optional[torch.Tensor],\n        masked_latents: Optional[torch.Tensor],\n        is_gradient_mask: bool,\n    ):\n        \"\"\"Initialize InpaintModelExt.\n        Args:\n            mask (Optional[torch.Tensor]): The inpainting mask. Shape: (1, 1, latent_height, latent_width). Values are\n                expected to be in the range [0, 1]. A value of 1 means that the corresponding 'pixel' should not be\n                inpainted.\n            masked_latents (Optional[torch.Tensor]): Latents of initial image, with masked out by black color inpainted area.\n                If mask provided, then too should be provided. Shape: (1, 1, latent_height, latent_width)\n            is_gradient_mask (bool): If True, mask is interpreted as a gradient mask meaning that the mask values range\n                from 0 to 1. If False, mask is interpreted as binary mask meaning that the mask values are either 0 or\n                1.\n        \"\"\"\n        super().__init__()\n        if mask is not None and masked_latents is None:\n            raise ValueError(\"Source image required for inpaint mask when inpaint model used!\")\n\n        # Inverse mask, because inpaint models treat mask as: 0 - remain same, 1 - inpaint\n        self._mask = None\n        if mask is not None:\n            self._mask = 1 - mask\n        self._masked_latents = masked_latents\n        self._is_gradient_mask = is_gradient_mask\n\n    @staticmethod\n    def _is_inpaint_model(unet: UNet2DConditionModel):\n        \"\"\"Checks if the provided UNet belongs to a regular model.\n        The `in_channels` of a UNet vary depending on model type:\n        - normal - 4\n        - depth - 5\n        - inpaint - 9\n        \"\"\"\n        return unet.conv_in.in_channels == 9\n","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/stable_diffusion/extensions/inpaint_model.py#L21-L57","documentation":"InpaintModelExt's constructor accepts an optional mask, but an inpainting UNet needs both the mask AND the latents of the masked source image to fill its extra 4 input channels. If a mask is given without masked_latents, the extension cannot compute its inputs and raises ValueError in __init__.","triggerScenarios":"Constructing InpaintModelExt(mask=mask, masked_latents=None) — any call where mask is not None but masked_latents is None.","commonSituations":"Inpaint jobs where the source image was missing or failed to encode; callers building the extension manually with only a mask; UI/API flows that allow mask upload without an image.","solutions":["Always pass masked_latents (VAE-encoded masked source image) alongside the mask.","Encode a blank/empty source image if no real source exists, producing valid masked_latents.","If inpainting is not intended, pass mask=None so the extension defaults to a global mask.","Fix the calling code so it never constructs the extension with a mask-only payload."],"exampleFix":"// before\next = InpaintModelExt(mask=mask, masked_latents=None)\n// after\nmasked_image_latents = vae.encode(source_image * (1 - mask))\next = InpaintModelExt(mask=mask, masked_latents=masked_image_latents)","handlingStrategy":"validation","validationCode":"if mask is not None and masked_latents is None:\n    raise ValueError(\"masked_latents must be provided together with mask\")","typeGuard":"def is_valid_inpaint_ext_args(mask, masked_latents) -> bool:\n    return mask is None or masked_latents is not None","tryCatchPattern":"try:\n    ext = InpaintModelExt(mask=mask, masked_latents=masked_latents)\nexcept ValueError:\n    ext = InpaintModelExt(mask=None, masked_latents=None)  # global-mask fallback","preventionTips":["Pair mask with VAE-encoded masked source latents","Encode a blank image when no source exists","Never build the extension from mask-only UI payloads","Unit-test inpaint arg construction in custom pipelines"],"tags":["python","valueerror","inpainting","missing-argument"],"backgroundTag":"missing-inpaint-source-image","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}