{"record":{"id":"86cbf7ef8728cb1e","repo":"invoke-ai/InvokeAI","slug":"expected-autoencoderklqwenimage-or-autoencoderklwa","errorCode":null,"errorMessage":"Expected AutoencoderKLQwenImage or AutoencoderKLWan, got {type(model).__name__}.","messagePattern":"Expected AutoencoderKLQwenImage or AutoencoderKLWan, got (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/krea2/vae_compat.py","lineNumber":48,"sourceCode":"\n\ndef as_qwen_image_vae(model: Any) -> QwenImageCompatibleVAE:\n    \"\"\"Return a cache-preserving VAE compatible with the Qwen-Image encode/decode path.\n\n    The only expected non-matching input is ``AutoencoderKLWan`` (the same weights loaded via the\n    Anima single-file path). A Wan VAE with the Qwen-Image geometry (16 latent channels, 8x spatial, no\n    patchification) has identical encode/decode behavior, state-dict layout, and default latent statistics,\n    so the cached module can be used directly. A Wan VAE with any other geometry (e.g. Wan 2.2's 48-channel,\n    patchified VAE) is rejected here rather than failing deeper in normalization/decode.\n\n    Returning the original object is important: the model cache injects custom modules for partial\n    loading before this helper is called, and rebuilding the module from its state dict would discard\n    those modules along with any hooks or layerwise-casting configuration.\n    \"\"\"\n    if isinstance(model, AutoencoderKLQwenImage):\n        return model\n    if not isinstance(model, AutoencoderKLWan):\n        raise TypeError(f\"Expected AutoencoderKLQwenImage or AutoencoderKLWan, got {type(model).__name__}.\")\n\n    config = model.config\n    z_dim = getattr(config, \"z_dim\", None)\n    patch_size = getattr(config, \"patch_size\", None)\n    spatial_scale = getattr(config, \"scale_factor_spatial\", _QWEN_IMAGE_VAE_SPATIAL_SCALE)\n    if z_dim != _QWEN_IMAGE_VAE_Z_DIM or patch_size is not None or spatial_scale != _QWEN_IMAGE_VAE_SPATIAL_SCALE:\n        raise ValueError(\n            \"AutoencoderKLWan is not Qwen-Image-compatible \"\n            f\"(z_dim={z_dim}, patch_size={patch_size}, scale_factor_spatial={spatial_scale}); \"\n            f\"expected {_QWEN_IMAGE_VAE_Z_DIM} latent channels, {_QWEN_IMAGE_VAE_SPATIAL_SCALE}x spatial, \"\n            \"and no patchification.\"\n        )\n\n    return model\n\n\n# The stock AutoencoderKLQwenImage tile geometry: 256px tiles advancing in 192px steps, i.e. a 3/4\n# stride ratio with a 64px blend band. Both nodes resolve tile_size=0 to QWEN_IMAGE_VAE_DEFAULT_TILE_SIZE","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/krea2/vae_compat.py#L30-L66","documentation":"as_qwen_image_vae adapts a VAE model for Krea-2/Qwen-Image latent space. It accepts an AutoencoderKLQwenImage as-is, or an AutoencoderKLWan for config-driven compatibility conversion; any other model type cannot be safely adapted (rebuilding from a state dict would drop hooks and layerwise-casting config), so it raises TypeError.","triggerScenarios":"Calling as_qwen_image_vae(model) (directly or via vae_encode/invoke) with a model that is neither AutoencoderKLQwenImage nor AutoencoderKLWan — e.g. AutoencoderKL (SD), AutoencoderKLLTXL, AutoencoderKLFlux, or a wrapped/quantized VAE object.","commonSituations":"Wiring a Stable Diffusion or other diffusion family's VAE into a Krea-2 pipeline by mistake; loading the wrong model config into the VAE slot; passing a custom subclass that does not inherit from the accepted classes.","solutions":["Load a Krea-2/Qwen-Image or Wan VAE and pass that instance instead.","Check type(model).__name__ before calling; route non-Wan/Qwen VAEs to their own encode path.","If using a custom VAE wrapper, inherit from AutoencoderKLQwenImage or unwrap the underlying model first.","Verify the model-loader config maps the correct VAE for the Krea-2 base model."],"exampleFix":"// before\nvae = load_vae('stabilityai/sd-vae-ft-mse')  # AutoencoderKL\nlatents = as_qwen_image_vae(vae).encode(...)\n// after\nvae = load_vae('Qwen/Qwen-Image', variant=AutoencoderKLQwenImage)\nlatents = as_qwen_image_vae(vae).encode(...)","handlingStrategy":"type-guard","validationCode":"from invokeai.backend.krea2.vae_compat import as_qwen_image_vae\nif not isinstance(vae, (AutoencoderKLQwenImage, AutoencoderKLWan)):\n    raise TypeError(f'{type(vae).__name__} cannot be used as a Krea-2 VAE')","typeGuard":"def is_krea2_compatible_vae(model) -> bool:\n    return isinstance(model, (AutoencoderKLQwenImage, AutoencoderKLWan))","tryCatchPattern":"try:\n    vae = as_qwen_image_vae(model)\nexcept TypeError as e:\n    if 'Expected AutoencoderKLQwenImage or AutoencoderKLWan' in str(e):\n        vae = load_correct_vae_for_base_model()\n    else:\n        raise","preventionTips":["Verify the VAE class matches the diffusion family before wiring pipelines","Keep model-loader configs mapping Krea-2 to its own VAE","Unwrap quantized/wrapped VAEs before passing to compat helpers","Add an isinstance check in any custom pipeline-assembly code"],"tags":["krea2","vae","type-error","model-compatibility"],"backgroundTag":"incompatible-model-type","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}