{"record":{"id":"7e99c0e619a20671","repo":"invoke-ai/InvokeAI","slug":"vae-is-required-when-using-z-image-control-connec","errorCode":null,"errorMessage":"VAE is required when using Z-Image Control. Connect a VAE to the 'vae' input.","messagePattern":"VAE is required when using Z-Image Control\\. Connect a VAE to the 'vae' input\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/z_image_denoise.py","lineNumber":472,"sourceCode":"                control_model_info = context.models.load(self.control.control_model)\n                (_, control_adapter) = exit_stack.enter_context(control_model_info.model_on_device())\n                assert isinstance(control_adapter, ZImageControlAdapter)\n\n                # Get control_in_dim from adapter config (16 for V1, 33 for V2.0)\n                adapter_config = control_adapter.config\n                control_in_dim = adapter_config.get(\"control_in_dim\", 16)\n                num_control_blocks = adapter_config.get(\"num_control_blocks\", 6)\n\n                # Log control configuration for debugging\n                version = \"V2.0\" if control_in_dim > 16 else \"V1\"\n                context.util.signal_progress(\n                    f\"Using Z-Image ControlNet {version} (Extension): control_in_dim={control_in_dim}, \"\n                    f\"num_blocks={num_control_blocks}, scale={self.control.control_context_scale}\"\n                )\n\n                # Load and prepare control image - must be VAE-encoded!\n                if self.vae is None:\n                    raise ValueError(\"VAE is required when using Z-Image Control. Connect a VAE to the 'vae' input.\")\n\n                control_image = context.images.get_pil(self.control.image_name)\n\n                # Resize control image to match output dimensions\n                control_image = control_image.convert(\"RGB\")\n                control_image = control_image.resize((self.width, self.height), Image.Resampling.LANCZOS)\n\n                # Convert to tensor format for VAE encoding\n                from invokeai.backend.stable_diffusion.diffusers_pipeline import image_resized_to_grid_as_tensor\n\n                control_image_tensor = image_resized_to_grid_as_tensor(control_image)\n                if control_image_tensor.dim() == 3:\n                    control_image_tensor = einops.rearrange(control_image_tensor, \"c h w -> 1 c h w\")\n\n                # Encode control image through VAE to get latents\n                vae_info = context.models.load(self.vae.vae)\n                control_latents = ZImageImageToLatentsInvocation.vae_encode(\n                    vae_info=vae_info,","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/z_image_denoise.py#L454-L490","documentation":"When a Z-Image ControlNet extension is active, the control image must be VAE-encoded into latent space, which requires a VAE model. If self.vae is None while a control network is configured, _run_diffusion raises ValueError telling the user to connect a VAE to the 'vae' input.","triggerScenarios":"invoke() on the Z-Image denoise invocation with a connected ControlNet (self.control set) but the 'vae' input left unconnected, so self.vae is None when the control image is prepared.","commonSituations":"Building a ControlNet workflow and forgetting the VAE connection; copying a denoise node from a non-control workflow; a workflow import that dropped the VAE edge.","solutions":["Connect a VAE model to the denoise invocation's 'vae' input","Use the same VAE as the rest of the pipeline to keep latent spaces consistent","Validate the graph: any control-connected denoise node must also have a VAE connection"],"exampleFix":"// before\ndenoise = ZImageDenoiseInvocation(control=controlnet, vae=None, ...)\n// after\ndenoise = ZImageDenoiseInvocation(control=controlnet, vae=vae_model_field, ...)","handlingStrategy":"validation","validationCode":"if denoise.control is not None and denoise.vae is None:\n    raise ValueError(\"ControlNet-connected Z-Image denoise requires a VAE on the 'vae' input\")","typeGuard":null,"tryCatchPattern":"try:\n    output = denoise.invoke(context)\nexcept ValueError as e:\n    if \"VAE is required\" in str(e):\n        raise GraphConfigError(\"connect a VAE node to the denoise 'vae' input\") from e\n    raise","preventionTips":["When adding a ControlNet node, always connect VAE in the same step","Template control workflows with the VAE edge pre-wired","Validate required edges before running imported workflows"],"tags":["controlnet","vae","missing-connection"],"backgroundTag":"missing-required-input","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}