{"record":{"id":"a4b7881076c6fffc","repo":"invoke-ai/InvokeAI","slug":"expected-autoencoderkl-or-fluxautoencoder-got-ty","errorCode":null,"errorMessage":"Expected AutoencoderKL or FluxAutoEncoder, got {type(vae).__name__}. VAE model type changed unexpectedly after loading.","messagePattern":"Expected AutoencoderKL or FluxAutoEncoder, got (.+?)\\. VAE model type changed unexpectedly after loading\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"invokeai/app/invocations/z_image_image_to_latents.py","lineNumber":60,"sourceCode":"\n    @staticmethod\n    def vae_encode(vae_info: LoadedModel, image_tensor: torch.Tensor) -> torch.Tensor:\n        if not isinstance(vae_info.model, (AutoencoderKL, FluxAutoEncoder)):\n            raise TypeError(\n                f\"Expected AutoencoderKL or FluxAutoEncoder for Z-Image VAE, got {type(vae_info.model).__name__}. \"\n                \"Ensure you are using a compatible VAE model.\"\n            )\n\n        # Estimate working memory needed for VAE encode\n        estimated_working_memory = estimate_vae_working_memory_flux(\n            operation=\"encode\",\n            image_tensor=image_tensor,\n            vae=vae_info.model,\n        )\n\n        with vae_info.model_on_device(working_mem_bytes=estimated_working_memory) as (_, vae):\n            if not isinstance(vae, (AutoencoderKL, FluxAutoEncoder)):\n                raise TypeError(\n                    f\"Expected AutoencoderKL or FluxAutoEncoder, got {type(vae).__name__}. \"\n                    \"VAE model type changed unexpectedly after loading.\"\n                )\n\n            vae_dtype = next(iter(vae.parameters())).dtype\n            image_tensor = image_tensor.to(device=TorchDevice.choose_torch_device(), dtype=vae_dtype)\n\n            with torch.inference_mode():\n                if isinstance(vae, FluxAutoEncoder):\n                    # FLUX VAE handles scaling internally\n                    generator = torch.Generator(device=TorchDevice.choose_torch_device()).manual_seed(0)\n                    latents = vae.encode(image_tensor, sample=True, generator=generator)\n                else:\n                    # AutoencoderKL - needs manual scaling\n                    vae.disable_tiling()\n                    image_tensor_dist = vae.encode(image_tensor).latent_dist\n                    latents: torch.Tensor = image_tensor_dist.sample().to(dtype=vae.dtype)\n","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/app/invocations/z_image_image_to_latents.py#L42-L78","documentation":"After loading the VAE onto the compute device with model_on_device, the code re-checks the model's runtime type. If it changed from AutoencoderKL/FluxAutoEncoder (checked before encode) to something else, this TypeError fires — a defensive guard against the model being swapped or wrapped unexpectedly during load/eviction.","triggerScenarios":"invoke() reaches the model_on_device context and the materialized vae_info.model object is not an AutoencoderKL/FluxAutoEncoder — typically due to concurrent model unloading/swapping in the RAM cache, or a model object wrapped/proxied by another loader path.","commonSituations":"Low-VRAM/RAM environments where the model cache evicts and reloads models mid-invocation; race conditions with parallel graph nodes sharing the same VAE; a loader wrapper changing the model class between the pre-check and on-device context.","solutions":["Retry the invocation (transient cache-swap race); avoid running competing generations that evict the same VAE","Increase RAM/VRAM headroom or model cache size to prevent mid-run eviction","Ensure only one workflow branch loads/mutates the shared VAE concurrently","If reproducible, re-import the VAE in the model manager and update InvokeAI"],"exampleFix":"// before\n# concurrent invocations evict the shared VAE mid-run -> TypeError\nrun(graph_a); run(graph_b)  # both share one VAE, low RAM\n// after\n# run sequentially or raise cache size so the VAE stays loaded\nrun(graph_a); run(graph_b)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"def is_decoded_vae(model) -> bool:\n    return isinstance(model, (AutoencoderKL, FluxAutoEncoder))","tryCatchPattern":"try:\n    latents = img2latents.invoke(context)\nexcept TypeError as e:\n    if \"VAE model type changed unexpectedly\" in str(e):\n        time.sleep(0.5)  # let model cache settle, then retry once\n        latents = img2latents.invoke(context)\n    else:\n        raise","preventionTips":["Avoid concurrent invocations that evict the same VAE from the low-RAM cache","Increase model cache capacity to keep hot VAEs resident","Retry transient model-loading TypeErrors once before failing the graph"],"tags":["vae","type-error","model-loading","race-condition"],"backgroundTag":"incompatible-model-type","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}