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 a {required_qwen3.value} encoder, but the {model_name} pipeline '{config.name}' ({source_variant.value}) carries {source_qwen3.value}. Select a Klein pipeline from the same family - 4B pairs with 4B, 9B with 9B. What it means
_validate_encoder_source raised ValueError because the Qwen3 encoder carried by the source pipeline does not match the size required by the main Klein model's variant (e.g. a 9B encoder on a 4B Klein transformer). The loader enforces same-family pairing: Klein 4B pairs with Qwen3 4B, Klein 9B with Qwen3 8B.
Source
Thrown at invokeai/app/invocations/flux2_klein_model_loader.py:250
"""
config = self._validate_diffusers_format(context, model, model_name)
source_variant = getattr(config, "variant", None)
source_qwen3 = _KLEIN_TO_QWEN3_VARIANT.get(source_variant)
# An allowlist, not "reject [dev]": a future third FLUX.2 variant has to fail closed here
# the way the [dev] loader's guard already makes it, rather than being silently accepted.
if source_qwen3 is None:
described = f"variant '{source_variant.value}'" if source_variant is not None else "not a Klein pipeline"
raise ValueError(
f"The {model_name} model must be a FLUX.2 Klein pipeline, "
f"but the selected model '{config.name}' is {described}. "
"Its text encoder is incompatible with the Klein transformer. "
"(Its VAE is compatible - this only blocks encoder extraction.)"
)
required_qwen3 = _KLEIN_TO_QWEN3_VARIANT.get(getattr(main_config, "variant", None))
if required_qwen3 is not None and source_qwen3 != required_qwen3:
raise ValueError(
f"Qwen3 encoder variant mismatch: FLUX.2 Klein {main_config.variant.value} requires a "
f"{required_qwen3.value} encoder, but the {model_name} pipeline '{config.name}' "
f"({source_variant.value}) carries {source_qwen3.value}. "
"Select a Klein pipeline from the same family - 4B pairs with 4B, 9B with 9B."
)
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`.View on GitHub (pinned to 0b6a024f2f)
Solutions
- Select a source Klein pipeline from the same family as the main model (4B pipeline for 4B model, 9B for 9B)
- Correct variant metadata on either model if the sizes actually match but tags differ
- Instead supply a standalone matching Qwen3 encoder via 'Qwen3 Encoder'
- Catch ValueError, read required vs source variants from both configs, and warn/redirect before invoke()
Example fix
// before main = klein_4b_model; loader.qwen3_source_model = klein_9b_pipeline # mismatch // after main_cfg = context.models.get_config(main) src_cfg = context.models.get_config(source_pipeline) assert _KLEIN_TO_QWEN3_VARIANT[main_cfg.variant] == _KLEIN_TO_QWEN3_VARIANT[src_cfg.variant] loader.qwen3_source_model = klein_4b_pipeline
Defensive patterns
Strategy: validation
Validate before calling
main_cfg = context.models.get_config(main_model)
src_cfg = context.models.get_config(source_pipeline)
req = _KLEIN_TO_QWEN3_VARIANT.get(getattr(main_cfg, 'variant', None))
src = _KLEIN_TO_QWEN3_VARIANT.get(getattr(src_cfg, 'variant', None))
if req is not None and src != req:
raise ValueError(f"encoder family mismatch: need {req}, source carries {src}") Type guard
def encoder_family_matches(main_cfg, source_cfg) -> bool:
return _KLEIN_TO_QWEN3_VARIANT.get(getattr(main_cfg, 'variant', None)) \
== _KLEIN_TO_QWEN3_VARIANT.get(getattr(source_cfg, 'variant', None)) Try / catch
try:
output = loader.invoke(context)
except ValueError as e:
if 'Qwen3 encoder variant mismatch' in str(e) and 'carries' in str(e):
loader.qwen3_source_model = select_same_family_pipeline(loader.model, context)
output = loader.invoke(context)
else:
raise Prevention
- Match Klein pipeline sizes explicitly (4B with 4B, 9B with 9B) when wiring sources
- Fix variant metadata after manual model imports
- Name/tag models by size family to avoid mix-ups
When it happens
Trigger: invoke() -> _validate_encoder_source where required_qwen3 = _KLEIN_TO_QWEN3_VARIANT[main_config.variant] exists but source_qwen3 (from the source pipeline's variant) differs from it.
Common situations: Mixing Klein 4B main model with a Klein 9B pipeline as encoder source (or vice versa); the model manager's variant tags mislabeled after manual import; grabbing whichever Klein pipeline is downloaded first.
Related errors
- The {model_name} model must be a FLUX.2 Klein pipeline, but
- Qwen3 encoder variant mismatch: FLUX.2 Klein {main_config.va
- LoRA "{lora_key}" already applied to Qwen3 encoder.
- Expected PreTrainedModel for text encoder, got {type(text_en
- Expected PreTrainedTokenizerBase for tokenizer, got {type(to
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/ba133d247c368cf7.
Report an issue: GitHub.