invoke-ai/InvokeAI · error · ValueError

Source image required for inpaint mask when inpaint model us

Error message

Source image required for inpaint mask when inpaint model used!

What it means

When the UNet is an inpainting model (9 input channels), the pipeline must concatenate mask and masked-reference-image latents at each denoising step. If a mask is supplied but masked_latents (the source-image latents) is None, the required channels cannot be built and ValueError is raised in step().

Source

Thrown at invokeai/backend/stable_diffusion/diffusers_pipeline.py:530

                required_padding_height = math.ceil(latents.size()[-2] / scale_factor) - tensor.size()[-2]
                tensor = torch.nn.functional.pad(
                    tensor,
                    (0, required_padding_width, 0, required_padding_height, 0, 0, 0, 0),
                    mode="constant",
                    value=0,
                )
                accum_adapter_state[idx] = tensor

            down_intrablock_additional_residuals = accum_adapter_state

        # Handle inpainting models.
        if is_inpainting_model(self.unet):
            # NOTE: These calls to add_inpainting_channels_to_latents(...) are intentionally done *after*
            # self.scheduler.scale_model_input(...) so that the scaling is not applied to the mask or reference image
            # latents.
            if mask is not None:
                if masked_latents is None:
                    raise ValueError("Source image required for inpaint mask when inpaint model used!")
                latent_model_input = self.add_inpainting_channels_to_latents(
                    latents=latent_model_input, masked_ref_image_latents=masked_latents, inpainting_mask=mask
                )
            else:
                # We are using an inpainting model, but no mask was provided, so we are not really "inpainting".
                # We generate a global mask and empty original image so that we can still generate in this
                # configuration.
                # TODO(ryand): Should we just raise an exception here instead? I can't think of a use case for wanting
                # to do this.
                # TODO(ryand): If we decide that there is a good reason to keep this, then we should generate the 'fake'
                # mask and original image once rather than on every denoising step.
                latent_model_input = self.add_inpainting_channels_to_latents(
                    latents=latent_model_input,
                    masked_ref_image_latents=torch.zeros_like(latent_model_input[:1]),
                    inpainting_mask=torch.ones_like(latent_model_input[:1, :1]),
                )

        uc_noise_pred, c_noise_pred = self.invokeai_diffuser.do_unet_step(

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Always provide masked_latents (latents of the masked source image) when passing a mask to an inpainting model.
  2. If no real source image exists, pass an empty/black image as the source so masked_latents can be computed.
  3. If you don't intend inpainting, omit the mask so the pipeline can synthesize a global mask and empty original image instead.
  4. Verify upstream pipeline args (mask vs masked_latents) are populated together by the caller.

Example fix

// before
pipeline.step(..., mask=mask, masked_latents=None)
// after
masked_latents = vae.encode(source_image * (1 - mask))
pipeline.step(..., mask=mask, masked_latents=masked_latents)
Defensive patterns

Strategy: validation

Validate before calling

if is_inpainting_model(pipeline.unet) and mask is not None:
    assert masked_latents is not None, "masked_latents required with mask for inpaint models"

Type guard

def has_complete_inpaint_args(mask, masked_latents) -> bool:
    return mask is None or masked_latents is not None

Try / catch

try:
    result = pipeline.latents_from_embeddings(...)
except ValueError as e:
    if "Source image required" in str(e):
        raise UserInputError("Provide a source image together with the inpaint mask") from e
    raise

Prevention

When it happens

Trigger: Calling pipeline.step(...) (or higher-level generation) with is_inpainting_model(unet)==True, passing a mask tensor but no masked_latents.

Common situations: Img2img/inpaint jobs where the user supplied a mask but the source image failed to encode or was dropped; API misuse calling low-level step() directly; regional/inpaint extension misconfiguration leaving masked_latents unset.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/f1cc2f656e8ad6d7. Report an issue: GitHub.