invoke-ai/InvokeAI · error · RuntimeError

Expected at least 1 hidden state, got {len(outputs.hidden_st

Error message

Expected at least 1 hidden state, got {len(outputs.hidden_states)}.

What it means

After confirming hidden_states exists, the code validates it is non-empty before indexing hidden_states[-1]. An empty tuple would produce an IndexError, so it raises a RuntimeError reporting how many hidden states were returned instead.

Source

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

            # 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,)

        return qwen3_embeds, t5xxl_ids, None

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Use the standard, fully-initialized Qwen3 PreTrainedModel so its layers emit hidden states.
  2. Verify the model weights loaded completely (no empty/pruned layer set).
  3. If wrapping the encoder, forward output_hidden_states through to the underlying model's forward call.

Example fix

// before
qwen3_embeds = outputs.hidden_states[-1][0]  # IndexError if empty
// after
if len(outputs.hidden_states) == 0:
    raise RuntimeError("no hidden states")
qwen3_embeds = outputs.hidden_states[-1][0]
Defensive patterns

Strategy: type-guard

Validate before calling

out = enc(**inputs, output_hidden_states=True)
assert out.hidden_states is not None and len(out.hidden_states) >= 1

Type guard

def has_hidden_states(output) -> bool:
    hs = getattr(output, "hidden_states", None)
    return hs is not None and len(hs) >= 1

Try / catch

try:
    result = invocation.invoke(context)
except RuntimeError as e:
    if "Expected at least 1 hidden state" in str(e):
        reload_fully_initialized_model()
    else:
        raise

Prevention

When it happens

Trigger: During invoke → _encode_prompt, when outputs.hidden_states is an empty tuple/sequence — essentially only possible with a broken or stubbed model whose forward produces no layer outputs despite output_hidden_states=True.

Common situations: Custom or partially-loaded model implementations; exotic quantization/wrapper paths that skip emitting layer hidden states; mock models in testing returning an empty tuple.

Related errors


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