huggingface/candle · error
unexpected shape for img {:?}
Error message
unexpected shape for img {:?} What it means
Same rank check as for txt but for img: FluxModel forward requires img (image token embeddings / latents) to be rank-3 [batch, img_seq, hidden]. A rank != 3 image tensor cannot be position-embedded and attention-processed, so forward bails.
Source
Thrown at candle-transformers/src/models/flux/quantized_model.rs:435
}
impl super::WithForward for Flux {
#[allow(clippy::too_many_arguments)]
fn forward(
&self,
img: &Tensor,
img_ids: &Tensor,
txt: &Tensor,
txt_ids: &Tensor,
timesteps: &Tensor,
y: &Tensor,
guidance: Option<&Tensor>,
) -> Result<Tensor> {
if txt.rank() != 3 {
candle::bail!("unexpected shape for txt {:?}", txt.shape())
}
if img.rank() != 3 {
candle::bail!("unexpected shape for img {:?}", img.shape())
}
let dtype = img.dtype();
let pe = {
let ids = Tensor::cat(&[txt_ids, img_ids], 1)?;
ids.apply(&self.pe_embedder)?
};
let mut txt = txt.apply(&self.txt_in)?;
let mut img = img.apply(&self.img_in)?;
let vec_ = timestep_embedding(timesteps, 256, dtype)?.apply(&self.time_in)?;
let vec_ = match (self.guidance_in.as_ref(), guidance) {
(Some(g_in), Some(guidance)) => {
(vec_ + timestep_embedding(guidance, 256, dtype)?.apply(g_in))?
}
_ => vec_,
};
let vec_ = (vec_ + y.apply(&self.vector_in))?;
// Double blocksView on GitHub (pinned to d5fee525bf)
Solutions
- Reshape latents to [batch, img_seq, hidden] — pack 2x2 patches via rearrange before calling forward
- Unsqueeze(0) if the batch dim is missing
- Confirm img.dims().len() == 3 prior to the call
Example fix
// before
let img = img; // [b, 16, h, w]
model.forward(&txt, &img, ...)?;
// after
let (b, _c, h, w) = img.dims4()?;
let img = img.reshape((b, 16, h / 2, 2, w / 2, 2))?
.permute((0, 2, 4, 1, 3, 5))?
.reshape((b, (h / 2) * (w / 2), 16 * 4))?;
model.forward(&txt, &img, ...)?; Defensive patterns
Strategy: validation
Validate before calling
assert_eq!(img.dims().len(), 3, "img must be [batch, img_seq, hidden], got {:?}", img.shape()); Type guard
fn is_rank3(t: &candle_core::Tensor) -> bool { t.rank() == 3 } Try / catch
match model.forward(&txt, &img, /* ... */) {
Err(e) if e.to_string().contains("unexpected shape for img") =>
Err(anyhow!("pack latents to token sequence [b, seq, d] before forward: {e}")),
r => r.map_err(Into::into),
} Prevention
- Pack conv-layout latents (b,c,h,w) into patch tokens before forward
- Keep batch dimension on image tensors even for single-image inference
- Reuse the flux example's prepare_latents/packing utilities
When it happens
Trigger: Passing latents as [b, c, h, w] (4D conv-style) without flattening to a token sequence, or a 2D [img_seq, hidden] tensor missing the batch dimension.
Common situations: Reusing latent tensors directly from a diffusion pipeline that keeps conv layout; forgetting to pack image patches into a sequence; manual inference scripts that skip Flux's latent packing step.
Understand the failure class
Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.
Related errors
- dim {dim} is odd
- {dim} is odd
- unexpected len from chunk {ys:?}
- unexpected shape for txt {:?}
- unexpected shape for img {:?}
AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02).
Data as JSON: /api/errors/bd3b6f2025b51e13.
Report an issue: GitHub.