{"record":{"id":"be04dd0f6a98d407","repo":"invoke-ai/InvokeAI","slug":"input-img-and-txt-tensors-must-have-3-dimensions-be04dd","errorCode":null,"errorMessage":"Input img and txt tensors must have 3 dimensions.","messagePattern":"Input img and txt tensors must have 3 dimensions\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/flux/controlnet/xlabs_controlnet_flux.py","lineNumber":100,"sourceCode":"            torch.nn.SiLU(),\n            torch.nn.Conv2d(16, 16, 3, padding=1, stride=2),\n            torch.nn.SiLU(),\n            zero_module(torch.nn.Conv2d(16, 16, 3, padding=1)),\n        )\n\n    def forward(\n        self,\n        img: torch.Tensor,\n        img_ids: torch.Tensor,\n        controlnet_cond: torch.Tensor,\n        txt: torch.Tensor,\n        txt_ids: torch.Tensor,\n        timesteps: torch.Tensor,\n        y: torch.Tensor,\n        guidance: torch.Tensor | None = None,\n    ) -> XLabsControlNetFluxOutput:\n        if img.ndim != 3 or txt.ndim != 3:\n            raise ValueError(\"Input img and txt tensors must have 3 dimensions.\")\n\n        # running on sequences img\n        img = self.img_in(img)\n        controlnet_cond = self.input_hint_block(controlnet_cond)\n        controlnet_cond = rearrange(controlnet_cond, \"b c (h ph) (w pw) -> b (h w) (c ph pw)\", ph=2, pw=2)\n        controlnet_cond = self.pos_embed_input(controlnet_cond)\n        img = img + controlnet_cond\n        vec = self.time_in(timestep_embedding(timesteps, 256))\n        if self.params.guidance_embed:\n            if guidance is None:\n                raise ValueError(\"Didn't get guidance strength for guidance distilled model.\")\n            vec = vec + self.guidance_in(timestep_embedding(guidance, 256))\n        vec = vec + self.vector_in(y)\n        txt = self.txt_in(txt)\n\n        ids = torch.cat((txt_ids, img_ids), dim=1)\n        pe = self.pe_embedder(ids)\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/flux/controlnet/xlabs_controlnet_flux.py#L82-L118","documentation":"XLabsControlNetFlux.forward expects sequence-form tokens: img (packed latent tokens) and txt (T5 text tokens) must both be 3D (batch, seq_len, channels). The controlnet_cond image goes through input_hint_block separately, so passing img/txt as 2D or 4D tensors breaks the token-stream contract and raises this ValueError.","triggerScenarios":"Calling forward() with img not patchified to (B, seq, dim) — e.g. a raw (B,C,H,W) latent — or txt squeezed to (B, C) or still 4D.","commonSituations":"Bypassing the pipeline's latent-packing step; removing the batch/sequence dim with .squeeze() when batch size is 1; mixing tensor layouts from diffusers-style code with this InvokeAI implementation.","solutions":["Pack img to (batch, seq_len, hidden) using the standard 2x2 patchify rearrange before calling forward.","Keep txt as (batch, t5_seq_len, 4096); avoid squeeze() that removes the seq dim.","Add assert img.ndim == 3 and txt.ndim == 3 in your caller to catch regressions.","Reuse the model's pipeline helpers for latent preparation instead of manual reshaping."],"exampleFix":"// before\ncontrolnet(img=latents, txt=t5_emb[:, 0, :], ...)  # 4D img, 2D txt\n// after\nimg_tokens = rearrange(latents, \"b c (h ph) (w pw) -> b (h w) (c ph pw)\", ph=2, pw=2)\ncontrolnet(img=img_tokens, txt=t5_emb, ...)","handlingStrategy":"validation","validationCode":"assert img.ndim == 3 and txt.ndim == 3, (\n    f\"expected (B, seq, dim): img={tuple(img.shape)}, txt={tuple(txt.shape)}\")","typeGuard":"def is_token_stream(t: torch.Tensor) -> bool:\n    return t.ndim == 3","tryCatchPattern":"try:\n    out = xlabs_controlnet(img=img, txt=txt, ...)\nexcept ValueError as e:\n    if \"must have 3 dimensions\" in str(e):\n        img = pack_latents(img)  # (B,C,H,W) -> (B, seq, dim)\n        out = xlabs_controlnet(img=img, txt=txt, ...)\n    else:\n        raise","preventionTips":["Route all tensor prep through the pipeline's packing utilities rather than manual reshapes.","Guard against batch-size-1 squeeze() collapsing the batch or seq dim.","Keep controlnet_cond separate — only img/txt need the token-stream layout."],"tags":["tensor-shape","validation","flux","xlabs"],"backgroundTag":"tensor-rank-mismatch","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}