huggingface/candle · error

text_embeddings cannot be empty

Error message

text_embeddings cannot be empty

What it means

pad_text_embeddings requires at least one text embedding tensor to batch and pad; when the input slice is empty there is no dimension/dtype to infer and no batch to produce, so it bails with 'text_embeddings cannot be empty' at candle-transformers/src/models/z_image/preprocess.rs:46. It is called from prepare_inputs, so this surfaces when preparing Z-Image model inputs.

Source

Thrown at candle-transformers/src/models/z_image/preprocess.rs:46

/// Pad variable-length text embeddings to uniform length
///
/// # Arguments
/// * `text_embeddings` - Variable-length text embeddings, each of shape (seq_len, dim)
/// * `pad_value` - Padding value (typically 0.0)
/// * `device` - Device
///
/// # Returns
/// * Padded tensor (B, max_len, dim)
/// * Attention mask (B, max_len), 1=valid, 0=padding
/// * Original lengths
pub fn pad_text_embeddings(
    text_embeddings: &[Tensor],
    pad_value: f32,
    device: &Device,
) -> Result<(Tensor, Tensor, Vec<usize>)> {
    if text_embeddings.is_empty() {
        candle::bail!("text_embeddings cannot be empty");
    }

    let batch_size = text_embeddings.len();
    let dim = text_embeddings[0].dim(1)?;
    let dtype = text_embeddings[0].dtype();

    // Compute max length and align to SEQ_MULTI_OF
    let lengths: Vec<usize> = text_embeddings
        .iter()
        .map(|t| t.dim(0))
        .collect::<Result<Vec<_>>>()?;
    let max_len = *lengths.iter().max().unwrap();
    let padded_len = max_len + compute_padding_len(max_len);

    // Build padded tensor and mask
    let mut padded_list = Vec::with_capacity(batch_size);
    let mut mask_list = Vec::with_capacity(batch_size);

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Ensure at least one text embedding tensor is produced before calling prepare_inputs/pad_text_embeddings — check that the prompt list is non-empty and the text encoder actually ran
  2. Guard the call site: return early or substitute a default embedding when the slice is empty
  3. Fix upstream filtering logic (masks, length cutoffs) that can empty the embeddings list
  4. If calling pad_text_embeddings directly, validate text_embeddings.len() > 0 before invoking

Example fix

// before
let (padded, mask, sizes) = pad_text_embeddings(&embeddings, 0.0, &device)?;
// after
if embeddings.is_empty() {
    anyhow::bail!("no text embeddings produced; check prompts and text encoder");
}
let (padded, mask, sizes) = pad_text_embeddings(&embeddings, 0.0, &device)?;
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_non_empty_embeddings(embeds: &[Tensor]) -> Result<(), String> {
    if embeds.is_empty() {
        return Err("text_embeddings cannot be empty".to_string());
    }
    Ok(())
}

Type guard

fn has_embeddings(embeds: &[Tensor]) -> bool { !embeds.is_empty() }

Try / catch

match pad_text_embeddings(&embeddings, 0.0, &device) {
    Ok((padded, mask, sizes)) => { /* proceed */ }
    Err(e) if e.to_string().contains("cannot be empty") => {
        eprintln!("no text embeddings produced; check prompts/text encoder: {e}");
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling pad_text_embeddings(&[], pad_value, &device) directly, or calling prepare_inputs with an empty list of text embeddings — typically when the text-encoding step produced no outputs (e.g. empty prompt list, encoder skipped, or embeddings filtered out upstream).

Common situations: Passing an empty prompt/batch list to an image-generation pipeline; filtering embeddings by a mask or length threshold that removes everything; forgetting to run the text-encoder step before prepare_inputs; collecting embeddings into a Vec that silently stayed empty due to an earlier error handled with a default.

Related errors


AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02). Data as JSON: /api/errors/6cac32df47d579c7. Report an issue: GitHub.