invoke-ai/InvokeAI · error · RuntimeError
Mistral encoder returned only {num_layers} hidden layer(s),
Error message
Mistral encoder returned only {num_layers} hidden layer(s), but FLUX.2 [dev] reads layers {DEV_EXTRACTION_LAYERS} and requires at least {max(DEV_EXTRACTION_LAYERS)}. This is not a supported FLUX.2 [dev] text encoder. What it means
_encode_prompt throws this RuntimeError when the Mistral encoder has fewer hidden layers than FLUX.2 [dev] requires. FLUX.2 [dev]'s joint attention was trained to read hidden states from layers DEV_EXTRACTION_LAYERS (10/20/30), so an encoder with fewer than 30 layers cannot satisfy the extraction indices. Rather than inventing indices that would yield degraded embeddings, the encoder is rejected loudly.
Source
Thrown at invokeai/app/invocations/flux2_dev_text_encoder.py:228
use_cache=False,
)
if not hasattr(outputs, "hidden_states") or outputs.hidden_states is None:
raise RuntimeError(
"Mistral encoder did not return hidden_states. "
"Ensure output_hidden_states=True is supported by this model."
)
num_hidden_states = len(outputs.hidden_states) # = num_hidden_layers + 1 (embedding output)
num_layers = num_hidden_states - 1
# The standalone Mistral encoder loaders only accept 30-layer cow or 40-layer
# Mistral Small 3 weights, so hidden_states[] should always contain the layers
# FLUX.2 [dev]'s joint attention was trained to read (10/20/30). A text encoder
# extracted from a Main_Diffusers_Flux2 pipeline, however, is loaded via generic
# from_pretrained with no layer-count validation — so a nonstandard pipeline with
# a <30-layer encoder could reach here. Fail loudly instead of inventing extraction
# indices that would silently produce off-distribution (degraded) embeddings.
if num_layers < max(DEV_EXTRACTION_LAYERS):
raise RuntimeError(
f"Mistral encoder returned only {num_layers} hidden layer(s), but FLUX.2 [dev] reads "
f"layers {DEV_EXTRACTION_LAYERS} and requires at least {max(DEV_EXTRACTION_LAYERS)}. "
"This is not a supported FLUX.2 [dev] text encoder."
)
extraction_layers = DEV_EXTRACTION_LAYERS
# Concatenate the selected layers along the hidden dim: (B, seq, 3 * hidden_size).
# This is byte-identical to stack(dim=1).permute(0,2,1,3).reshape(...) but avoids
# the two intermediate full copies that stack + permute-reshape would allocate.
prompt_embeds = torch.cat([outputs.hidden_states[i] for i in extraction_layers], dim=-1)
prompt_embeds = prompt_embeds.to(dtype=text_encoder.dtype, device=device)
return prompt_embeds
def _lora_iterator(self, context: InvocationContext) -> Iterator[Tuple[ModelPatchRaw, float]]:
"""Iterate over LoRAs to apply to the Mistral encoder."""
for lora in self.mistral_encoder.loras:
lora_info = context.models.load(lora.lora)View on GitHub (pinned to 0b6a024f2f)
Solutions
- Supply the full Mistral Small 3.1 text encoder (with at least 30 hidden layers) as the encoder source.
- Extract the encoder from a genuine FLUX.2 [dev] Diffusers pipeline rather than a nonstandard or distilled pipeline.
- Verify the encoder config's num_hidden_layers is >= 30 before loading.
Example fix
// before encoder = tiny_distilled_mistral_encoder // 16 layers // after encoder = mistral_small_3_1_full // >= 30 layers
Defensive patterns
Strategy: validation
Validate before calling
cfg = encoder.config
if getattr(cfg, "num_hidden_layers", 0) < max(DEV_EXTRACTION_LAYERS):
raise ValueError(f"Encoder has {cfg.num_hidden_layers} layers; FLUX.2 [dev] needs >= {max(DEV_EXTRACTION_LAYERS)}") Type guard
def supports_flux2_dev_extraction(encoder) -> bool:
return getattr(encoder.config, "num_hidden_layers", 0) >= max(DEV_EXTRACTION_LAYERS) Try / catch
try:
output = text_encoder_invocation.invoke(context)
except RuntimeError as e:
if "hidden layer(s)" in str(e) and "not a supported FLUX.2 [dev] text encoder" in str(e):
encoder = load_full_mistral_small_3_1()
output = retry_encoding(encoder)
else:
raise Prevention
- Check num_hidden_layers >= 30 in the encoder config before use.
- Extract encoders only from official FLUX.2 [dev] Diffusers pipelines.
- Avoid distilled/quantized encoder variants for [dev] conditioning.
When it happens
Trigger: outputs.hidden_states has length <= 30 (num_layers < max(DEV_EXTRACTION_LAYERS)); possible because Diffusers-pipeline encoders load via generic from_pretrained with no layer validation.
Common situations: A nonstandard FLUX.2 Diffusers pipeline with a small/short Mistral-compatible encoder (e.g. a distilled or Klein-family encoder) is supplied as the encoder source and passes earlier checks.
Related errors
- No Mistral encoder source provided. Single-file / GGUF trans
- The {model_name} model must be a FLUX.2 [dev] pipeline, but
- Expected PreTrainedModel for text encoder, got {type(text_en
- Mistral encoder did not return hidden_states. Ensure output_
- Expected PreTrainedModel for text encoder, got {type(text_en
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/094fb45b4f0a0c2c.
Report an issue: GitHub.