invoke-ai/InvokeAI · error · ValueError

AutoencoderKLWan is not Qwen-Image-compatible (z_dim={z_dim}

Error message

AutoencoderKLWan is not Qwen-Image-compatible (z_dim={z_dim}, patch_size={patch_size}, scale_factor_spatial={spatial_scale}); expected {_QWEN_IMAGE_VAE_Z_DIM} latent channels, {_QWEN_IMAGE_VAE_SPATIAL_SCALE}x spatial, and no patchification.

What it means

When given an AutoencoderKLWan, as_qwen_image_vae checks that its config matches Qwen-Image latent expectations: z_dim equal to _QWEN_IMAGE_VAE_Z_DIM (16), patch_size unset/None (no patchification), and scale_factor_spatial equal to the Qwen-Image spatial scale. Wan VAEs that fail any check (e.g. Wan 2.2's 48-channel VAE) would silently produce wrong latents, so a ValueError is raised.

Source

Thrown at invokeai/backend/krea2/vae_compat.py:55

    patchification) has identical encode/decode behavior, state-dict layout, and default latent statistics,
    so the cached module can be used directly. A Wan VAE with any other geometry (e.g. Wan 2.2's 48-channel,
    patchified VAE) is rejected here rather than failing deeper in normalization/decode.

    Returning the original object is important: the model cache injects custom modules for partial
    loading before this helper is called, and rebuilding the module from its state dict would discard
    those modules along with any hooks or layerwise-casting configuration.
    """
    if isinstance(model, AutoencoderKLQwenImage):
        return model
    if not isinstance(model, AutoencoderKLWan):
        raise TypeError(f"Expected AutoencoderKLQwenImage or AutoencoderKLWan, got {type(model).__name__}.")

    config = model.config
    z_dim = getattr(config, "z_dim", None)
    patch_size = getattr(config, "patch_size", None)
    spatial_scale = getattr(config, "scale_factor_spatial", _QWEN_IMAGE_VAE_SPATIAL_SCALE)
    if z_dim != _QWEN_IMAGE_VAE_Z_DIM or patch_size is not None or spatial_scale != _QWEN_IMAGE_VAE_SPATIAL_SCALE:
        raise ValueError(
            "AutoencoderKLWan is not Qwen-Image-compatible "
            f"(z_dim={z_dim}, patch_size={patch_size}, scale_factor_spatial={spatial_scale}); "
            f"expected {_QWEN_IMAGE_VAE_Z_DIM} latent channels, {_QWEN_IMAGE_VAE_SPATIAL_SCALE}x spatial, "
            "and no patchification."
        )

    return model


# The stock AutoencoderKLQwenImage tile geometry: 256px tiles advancing in 192px steps, i.e. a 3/4
# stride ratio with a 64px blend band. Both nodes resolve tile_size=0 to QWEN_IMAGE_VAE_DEFAULT_TILE_SIZE
# rather than reading the module's current value, which another invocation may have overwritten.
QWEN_IMAGE_VAE_DEFAULT_TILE_SIZE = 256
_QWEN_IMAGE_VAE_TILE_STRIDE_NUMERATOR = 3
_QWEN_IMAGE_VAE_TILE_STRIDE_DENOMINATOR = 4

# A cost floor, not a correctness one: `_tile_stride_for` keeps the geometry valid all the way down
# (smaller tiles decode and encode to the right size), but the tile *count* grows with the inverse

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Use a Wan VAE with 16 latent channels, no patchification, and the standard spatial scale (Wan 2.1-style).
  2. Inspect model.config (z_dim, patch_size, scale_factor_spatial) before calling and pick a compatible checkpoint.
  3. If you believe the VAE is compatible, fix its config values or remove patch_size.
  4. Update InvokeAI in case newer versions support additional Wan VAE variants.

Example fix

// before
vae = load_wan_vae('Wan2.2-VAE48')  # z_dim=48, rejected
// after
vae = load_wan_vae('Wan2.1-VAE')     # z_dim=16, no patching
latents = as_qwen_image_vae(vae)
Defensive patterns

Strategy: validation

Validate before calling

cfg = model.config
if (getattr(cfg, 'z_dim', None) != 16
        or getattr(cfg, 'patch_size', None) is not None
        or getattr(cfg, 'scale_factor_spatial', 8) != 8):
    raise ValueError('Wan VAE is not Qwen-Image-compatible; use a 16-channel, unpatched Wan 2.1-style VAE')

Type guard

def is_qwen_compatible_wan_vae(model) -> bool:
    cfg = model.config
    return (getattr(cfg, 'z_dim', None) == _QWEN_IMAGE_VAE_Z_DIM
            and getattr(cfg, 'patch_size', None) is None
            and getattr(cfg, 'scale_factor_spatial', _QWEN_IMAGE_VAE_SPATIAL_SCALE) == _QWEN_IMAGE_VAE_SPATIAL_SCALE)

Try / catch

try:
    vae = as_qwen_image_vae(wan_model)
except ValueError as e:
    if 'not Qwen-Image-compatible' in str(e):
        vae = load_wan_vae_2_1()  # known-compatible variant
    else:
        raise

Prevention

When it happens

Trigger: Calling as_qwen_image_vae with a Wan VAE whose config has z_dim != 16, a non-None patch_size, or scale_factor_spatial != the expected value — classically the Wan 2.2 48-channel VAE.

Common situations: Pointing Krea-2 at a Wan 2.2 (48ch) or patched Wan VAE downloaded from another repo; a model cache that loaded a different Wan variant; changed scale factors in custom configs.

Related errors


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