invoke-ai/InvokeAI · error · RuntimeError

Text encoder did not return hidden_states.

Error message

Text encoder did not return hidden_states.

What it means

The forward pass requests output_hidden_states=True, so the model output must carry a hidden_states tuple. If the output object lacks the attribute or it is None, _encode_prompt raises a RuntimeError, because it builds the prompt embeddings from the last hidden state.

Source

Thrown at invokeai/app/invocations/anima_text_encoder.py:189

                    "Consider shortening the prompt for best results."
                )

            # Ensure at least 1 token (empty prompts produce 0 tokens with padding=False)
            if text_input_ids.shape[-1] == 0:
                pad_id = tokenizer.pad_token_id if tokenizer.pad_token_id is not None else tokenizer.eos_token_id
                text_input_ids = torch.tensor([[pad_id]])
                attention_mask = torch.tensor([[1]])

            # Get last hidden state from Qwen3 (final layer output)
            prompt_mask = attention_mask.to(device).bool()
            outputs = text_encoder(
                text_input_ids.to(device),
                attention_mask=prompt_mask,
                output_hidden_states=True,
            )

            if not hasattr(outputs, "hidden_states") or outputs.hidden_states is None:
                raise RuntimeError("Text encoder did not return hidden_states.")
            if len(outputs.hidden_states) < 1:
                raise RuntimeError(f"Expected at least 1 hidden state, got {len(outputs.hidden_states)}.")

            # Use last hidden state — only real tokens, no padding
            qwen3_embeds = outputs.hidden_states[-1][0]  # Shape: (seq_len, 1024)

        # --- Step 2: Tokenize with bundled T5-XXL tokenizer (IDs only, no model) ---
        context.util.signal_progress("Tokenizing with T5-XXL")
        t5_tokenizer = load_bundled_t5_tokenizer()
        t5_tokens = t5_tokenizer(
            prompt,
            padding=False,
            truncation=True,
            max_length=T5_MAX_SEQ_LEN,
            return_tensors="pt",
        )
        t5xxl_ids = t5_tokens.input_ids[0]  # Shape: (seq_len,)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Load the official Qwen3 base model class via AutoModel so forward returns a ModelOutput with hidden_states.
  2. Check that output_hidden_states=True is passed (as the code does) and that no wrapper strips it.
  3. Align the transformers library version with InvokeAI's pinned requirements and reconvert the model.
Defensive patterns

Strategy: type-guard

Validate before calling

from transformers import AutoModel
enc = AutoModel.from_pretrained(model_path)
out = enc(**inputs, output_hidden_states=True)
assert getattr(out, "hidden_states", None) is not None

Type guard

def returns_hidden_states(output) -> bool:
    return hasattr(output, "hidden_states") and output.hidden_states is not None

Try / catch

try:
    result = invocation.invoke(context)
except RuntimeError as e:
    if "did not return hidden_states" in str(e):
        reload_with_stock_pretrained_model()
    else:
        raise

Prevention

When it happens

Trigger: During invoke → _encode_prompt, when calling text_encoder(input_ids, attention_mask, output_hidden_states=True) returns an output object without hidden_states — e.g. the loaded model is not a real PreTrainedModel forward, or its config disables output hidden states / returns a plain tensor.

Common situations: A model subclass whose forward returns a tensor instead of a ModelOutput; incompatible transformers version changing the output type; a wrapper (e.g. for quantization/ONNX) that drops the hidden_states field.

Related errors


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