{"record":{"id":"d75f442bf30cde1a","repo":"invoke-ai/InvokeAI","slug":"initial-latents-are-required-when-a-denoise-mask-i","errorCode":null,"errorMessage":"Initial latents are required when a denoise mask is provided.","messagePattern":"Initial latents are required when a denoise mask is provided\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/krea2_denoise.py","lineNumber":233,"sourceCode":"        raise ValueError(f\"Invalid CFG scale type: {type(self.cfg_scale)}\")\n\n    @staticmethod\n    def _should_apply_cfg_for_step(cfg_scale: float, *, has_negative_conditioning: bool) -> bool:\n        return has_negative_conditioning and cfg_scale > 1.0\n\n    @staticmethod\n    def _validate_effective_schedule(*, start_idx: int, end_idx: int) -> None:\n        if end_idx <= start_idx:\n            raise ValueError(\n                \"The requested denoising range does not contain any effective denoising steps at the configured \"\n                \"step count. Increase denoising_end, decrease denoising_start, or increase steps.\"\n            )\n\n    def _validate_inputs(self) -> None:\n        if self.denoising_start >= self.denoising_end:\n            raise ValueError(\"denoising_start must be less than denoising_end.\")\n        if self.denoise_mask is not None and self.latents is None:\n            raise ValueError(\"Initial latents are required when a denoise mask is provided.\")\n\n    def _is_distilled(self, context: InvocationContext) -> bool:\n        \"\"\"Whether the transformer is the distilled Turbo checkpoint (fixed mu) vs. Raw (dynamic mu).\n\n        Prefer the classified variant (works for diffusers, single-file and GGUF alike); fall back to\n        the pipeline-level ``is_distilled`` flag in model_index.json, then default to distilled.\n\n        A failed config lookup is a real error and is allowed to propagate — silently defaulting to the\n        Turbo shift would apply the wrong sampling schedule to a Raw model.\n        \"\"\"\n        from invokeai.backend.model_manager.taxonomy import Krea2VariantType\n\n        config = context.models.get_config(self.transformer.transformer)\n        variant = getattr(config, \"variant\", None)\n        if variant is not None:\n            return variant != Krea2VariantType.Base\n        # No classified variant (unexpected for Krea-2) — fall back to the pipeline-level flag. Only a\n        # missing/malformed model_index.json is tolerated here; it defaults to the distilled behavior.","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/krea2_denoise.py#L215-L251","documentation":"A denoise mask tells the pipeline which latent regions to preserve, which only makes sense when there are initial latents to mask. `_validate_inputs` raises this ValueError when denoise_mask is provided but the `latents` input is None.","triggerScenarios":"Connecting a DenoiseMaskField to the krea2_denoise node while leaving the latents input unconnected — e.g. running txt2img with a mask instead of img2img/inpaint.","commonSituations":"Inpainting graphs where the initial-image/VAE-encode branch was disconnected; users expecting mask-based txt2img; workflow templates missing the latents edge.","solutions":["Connect initial latents (from a VAE Encode or Resize Latents node output) to the invocation's latents input.","If no initial image is intended, remove the denoise_mask connection.","Check the workflow for a disabled or deleted node upstream of the latents input."],"exampleFix":"// before: mask without latents\nDenoiseInvocation(denoise_mask=mask, latents=None)\n// after: provide initial latents\nDenoiseInvocation(denoise_mask=mask, latents=vae_encode.latents)","handlingStrategy":"validation","validationCode":"if denoise_mask is not None and latents is None:\n    raise ValueError(\"Provide initial latents (e.g. VAE Encode output) when using a denoise mask.\")","typeGuard":"def mask_has_latents(denoise_mask, latents) -> bool:\n    return denoise_mask is None or latents is not None","tryCatchPattern":"try:\n    out = invoke_krea2_denoise(denoise_mask=mask, latents=latents)\nexcept ValueError as e:\n    if \"Initial latents are required\" in str(e):\n        latents = vae_encode(image).latents\n        out = invoke_krea2_denoise(denoise_mask=mask, latents=latents)\n    else:\n        raise","preventionTips":["Always pair a DenoiseMaskField with a latents input in graph templates.","Validate inpainting graphs for a connected image -> VAE Encode -> latents path.","Remove mask connections when running pure txt2img."],"tags":["invokeai","krea2","missing-input","inpainting"],"backgroundTag":"missing-required-input","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}