invoke-ai/InvokeAI · error · ValueError

Qwen3 encoder variant mismatch: FLUX.2 Klein {main_config.va

Error message

Qwen3 encoder variant mismatch: FLUX.2 Klein {main_config.variant.value} requires {expected_qwen3_variant.value} encoder, but {qwen3_variant.value} was selected. Please select a matching Qwen3 encoder or use a Diffusers format model which includes the correct encoder.

What it means

_validate_qwen3_encoder_variant raised ValueError because the standalone Qwen3 encoder selected via 'Qwen3 Encoder' has a variant that differs from the one required by the main Klein model's variant (e.g. Qwen3 8B chosen for Klein 4B). The check is skipped when the encoder config has no variant. The message suggests a matching encoder or a Diffusers model bundling the right one.

Source

Thrown at invokeai/app/invocations/flux2_klein_model_loader.py:275

    def _validate_qwen3_encoder_variant(self, context: InvocationContext, main_config: AnyModelConfig) -> None:
        """Validate that the standalone Qwen3 encoder variant matches the FLUX.2 Klein variant.

        - FLUX.2 Klein 4B (and 4B Base) require the Qwen3 4B encoder
        - FLUX.2 Klein 9B (and 9B Base) require the Qwen3 8B encoder
        """
        if self.qwen3_encoder_model is None:
            return

        # `getattr(..., None)` rather than `hasattr`: the field can exist and still be None, and
        # comparing None against the expected variant would then raise `AttributeError` on
        # `.value` in the error path instead of the intended `ValueError`.
        qwen3_variant = getattr(context.models.get_config(self.qwen3_encoder_model), "variant", None)
        if qwen3_variant is None:
            return

        expected_qwen3_variant = _KLEIN_TO_QWEN3_VARIANT.get(getattr(main_config, "variant", None))
        if expected_qwen3_variant is not None and qwen3_variant != expected_qwen3_variant:
            raise ValueError(
                f"Qwen3 encoder variant mismatch: FLUX.2 Klein {main_config.variant.value} requires "
                f"{expected_qwen3_variant.value} encoder, but {qwen3_variant.value} was selected. "
                "Please select a matching Qwen3 encoder or use a Diffusers format model which includes the correct encoder."
            )

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Select the Qwen3 encoder matching the main model's family (Qwen3 4B for Klein 4B, Qwen3 8B for Klein 9B)
  2. Switch to a Diffusers-format Klein model whose bundled encoder is guaranteed correct
  3. Install the missing matching Qwen3 encoder via the model manager
  4. Fix variant metadata if the encoder is actually the right size but tagged incorrectly
  5. Catch ValueError and compare variants before invoke()

Example fix

// before
loader.qwen3_encoder_model = qwen3_8b_encoder  # main model is Klein 4B
// after
main_cfg = context.models.get_config(loader.model)
enc_cfg = context.models.get_config(loader.qwen3_encoder_model)
assert _KLEIN_TO_QWEN3_VARIANT[main_cfg.variant] == enc_cfg.variant
output = loader.invoke(context)
Defensive patterns

Strategy: validation

Validate before calling

main_cfg = context.models.get_config(loader.model)
enc_cfg = context.models.get_config(loader.qwen3_encoder_model)
expected = _KLEIN_TO_QWEN3_VARIANT.get(getattr(main_cfg, 'variant', None))
enc_variant = getattr(enc_cfg, 'variant', None)
if expected is not None and enc_variant is not None and enc_variant != expected:
    raise ValueError(f"need {expected} encoder, got {enc_variant}")

Type guard

def encoder_variant_ok(main_cfg, encoder_cfg) -> bool:
    expected = _KLEIN_TO_QWEN3_VARIANT.get(getattr(main_cfg, 'variant', None))
    enc = getattr(encoder_cfg, 'variant', None)
    return expected is None or enc is None or enc == expected

Try / catch

try:
    output = loader.invoke(context)
except ValueError as e:
    if 'Qwen3 encoder variant mismatch' in str(e) and 'was selected' in str(e):
        loader.qwen3_encoder_model = select_matching_qwen3_encoder(loader.model, context)
        output = loader.invoke(context)
    else:
        raise

Prevention

When it happens

Trigger: invoke() -> _validate_qwen3_encoder_variant where qwen3_variant = context.models.get_config(self.qwen3_encoder_model).variant is not None, expected_qwen3_variant = _KLEIN_TO_QWEN3_VARIANT[main_config.variant] exists, and the two differ.

Common situations: Klein 4B workflow wired to a Qwen3 8B encoder (or 9B to 4B); user selected the only Qwen3 encoder installed regardless of size; variant metadata wrong after manual model import.

Related errors


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