Comfy-Org/ComfyUI · critical · ValueError
Input img tensor must be in [B, C, H, W] format.
Error message
Input img tensor must be in [B, C, H, W] format.
What it means
ChromaRadiance._forward expects the raw image/latent tensor x in [B, C, H, W]; after pad_to_patch_size it checks img.ndim == 4 before building positional ids over H/p x W/p patches. A non-4-D input (e.g. an already-tokenized [B, seq, dim] tensor, or a missing-batch [C, H, W] latent) fails immediately. Unlike Chroma's check (which validates the patchified 3-D tokens), radiance works on the 4-D image through its own conv patchifier, hence the different dimensionality contract.
Source
Thrown at comfy/ldm/chroma_radiance/model.py:307
# non zero during training to prevent 0 div
eps = 0.0
return (noisy - predicted) / (timesteps.view(-1,1,1,1) + eps)
def _forward(
self,
x: Tensor,
timestep: Tensor,
context: Tensor,
guidance: Optional[Tensor],
control: Optional[dict]=None,
transformer_options: dict={},
**kwargs: dict,
) -> Tensor:
bs, c, h, w = x.shape
img = comfy.ldm.common_dit.pad_to_patch_size(x, (self.patch_size, self.patch_size))
if img.ndim != 4:
raise ValueError("Input img tensor must be in [B, C, H, W] format.")
if context.ndim != 3:
raise ValueError("Input txt tensors must have 3 dimensions.")
params = self.radiance_get_override_params(transformer_options.get("chroma_radiance_options", {}))
h_len = (img.shape[-2] // self.patch_size)
w_len = (img.shape[-1] // self.patch_size)
img_ids = torch.zeros((h_len, w_len, 3), device=x.device, dtype=x.dtype)
img_ids[:, :, 1] = img_ids[:, :, 1] + torch.linspace(0, h_len - 1, steps=h_len, device=x.device, dtype=x.dtype).unsqueeze(1)
img_ids[:, :, 2] = img_ids[:, :, 2] + torch.linspace(0, w_len - 1, steps=w_len, device=x.device, dtype=x.dtype).unsqueeze(0)
img_ids = repeat(img_ids, "h w c -> b (h w) c", b=bs)
txt_ids = torch.zeros((bs, context.shape[1], 3), device=x.device, dtype=x.dtype)
# Radiance after 2026-05-22 uses sequential txt_ids instead of zeros
if params.use_sequential_txt_ids:
txt_ids[:, :, 0] = torch.arange(context.shape[1], device=x.device, dtype=x.dtype).unsqueeze(0).expand(bs, -1)
img_out = self.forward_orig(View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Pass a 4-D latent/image tensor [B, C, H, W]; add the batch dim with x.unsqueeze(0) if missing
- Do not pre-patchify: the model applies img_in_patch (Conv2d with stride=patch_size) itself
- Route through the standard model patcher / sampling loop instead of calling _forward directly
Example fix
# before out = model(x=latent[0], ...) # [C, H, W] -> fails ndim check path # after latent = latent.unsqueeze(0) if latent.ndim == 3 else latent out = model(x=latent, ...)
Defensive patterns
Strategy: validation
Validate before calling
if x.ndim == 3:
x = x.unsqueeze(0)
assert x.ndim == 4, f"expected [B, C, H, W], got {tuple(x.shape)}" Type guard
def is_bchw(t) -> bool:
return isinstance(t, torch.Tensor) and t.ndim == 4 Prevention
- Always feed 4-D latents/images to radiance forwards
- Do not pre-patchify inputs; the model's img_in_patch conv does it
When it happens
Trigger: Calling ChromaRadiance._forward with x of shape [C, H, W] (unbatched), [B, seq, dim] (pre-tokenized), or a 5-D video-style tensor. The unpack 'bs, c, h, w = x.shape' one line earlier would itself fail for other ranks, so in practice this guard catches 4-D-shaped edge cases after padding and documents the contract.
Common situations: Custom nodes feeding radiance models pre-patchified features; dropping the batch dim when batching tiles manually; porting Chroma call code (which passes latents the same way) but with tensors already converted to sequence form.
Related errors
- Input txt tensors must have 3 dimensions.
- Input img and txt tensors must have 3 dimensions.
- Input img and txt tensors must have 3 dimensions.
- Attempt to create ChromaRadiance object without setting oper
- Hidden size {params.hidden_size} must be divisible by num_he
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/3f5f52b577cfe0a8.
Report an issue: GitHub.