{"record":{"id":"eeae3a6f384c6c50","repo":"huggingface/candle","slug":"unexpected-shape-for-txt-eeae3a","errorCode":null,"errorMessage":"unexpected shape for txt {:?}","messagePattern":"unexpected shape for txt (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-transformers/src/models/flux/quantized_model.rs","lineNumber":432,"sourceCode":"            final_layer,\n        })\n    }\n}\n\nimpl super::WithForward for Flux {\n    #[allow(clippy::too_many_arguments)]\n    fn forward(\n        &self,\n        img: &Tensor,\n        img_ids: &Tensor,\n        txt: &Tensor,\n        txt_ids: &Tensor,\n        timesteps: &Tensor,\n        y: &Tensor,\n        guidance: Option<&Tensor>,\n    ) -> Result<Tensor> {\n        if txt.rank() != 3 {\n            candle::bail!(\"unexpected shape for txt {:?}\", txt.shape())\n        }\n        if img.rank() != 3 {\n            candle::bail!(\"unexpected shape for img {:?}\", img.shape())\n        }\n        let dtype = img.dtype();\n        let pe = {\n            let ids = Tensor::cat(&[txt_ids, img_ids], 1)?;\n            ids.apply(&self.pe_embedder)?\n        };\n        let mut txt = txt.apply(&self.txt_in)?;\n        let mut img = img.apply(&self.img_in)?;\n        let vec_ = timestep_embedding(timesteps, 256, dtype)?.apply(&self.time_in)?;\n        let vec_ = match (self.guidance_in.as_ref(), guidance) {\n            (Some(g_in), Some(guidance)) => {\n                (vec_ + timestep_embedding(guidance, 256, dtype)?.apply(g_in))?\n            }\n            _ => vec_,\n        };","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-transformers/src/models/flux/quantized_model.rs#L414-L450","documentation":"FluxModel forward requires txt (text token embeddings) to be a rank-3 tensor [batch, seq_len, hidden]. If the txt tensor's rank differs, forward bails early with the shape. This guards downstream ops (concatenation with img_ids, attention) that assume 3 dims.","triggerScenarios":"Calling FluxModel forward with a txt tensor built from tokenizer output of wrong rank — e.g. squeezed to 2D [seq, hidden], 1D flat embeddings, or 4D batched-with-channels tensor.","commonSituations":"Pre-processing text embeddings yourself instead of using the provided encode path; forgetting to unsqueeze a batch dimension; passing CLIP/T5 hidden states without reshaping to [b, seq, d].","solutions":["Ensure txt is shape [batch, seq_len, hidden_size], unsqueeze(0) if missing batch dim","Check rank before calling: txt.dims().len() == 3","Use the model's own text-encoding helper rather than hand-built tensors"],"exampleFix":"// before\nmodel.forward(&txt, &img, &txt_ids, &img_ids, &timesteps, &y, guidance)?;\n// after\nlet txt = if txt.rank() == 2 { txt.unsqueeze(0)? } else { txt };\nmodel.forward(&txt, &img, &txt_ids, &img_ids, &timesteps, &y, guidance)?;","handlingStrategy":"validation","validationCode":"assert_eq!(txt.dims().len(), 3, \"txt must be [batch, seq, hidden], got {:?}\", txt.shape());","typeGuard":"fn is_rank3(t: &candle_core::Tensor) -> bool { t.rank() == 3 }","tryCatchPattern":"match model.forward(&txt, &img, /* ... */) {\n    Err(e) if e.to_string().contains(\"unexpected shape for txt\") =>\n        Err(anyhow!(\"reshape txt to [batch, seq, hidden]: {e}\")),\n    r => r.map_err(Into::into),\n}","preventionTips":["Always unsqueeze batch dimension on text embeddings","Use candle's flux example text-encoding path instead of ad-hoc tensor building","Log tensor ranks/shapes right before forward calls during development"],"tags":["tensor-shape","flux","input-validation"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}