{"record":{"id":"b902b957ab4feaa1","repo":"invoke-ai/InvokeAI","slug":"color-tensor-must-be-a-3xhxw-tensor","errorCode":null,"errorMessage":"color_tensor must be a 3xHxW tensor","messagePattern":"color_tensor must be a 3xHxW tensor","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/image_util/color_conversion.py","lineNumber":56,"sourceCode":"    (0.2104542553, 0.7936177850, -0.0040720468),\n    (1.9779984951, -2.4285922050, 0.4505937099),\n    (0.0259040371, 0.7827717662, -0.8086757660),\n)\n_OKLAB_TO_LMS_CUBE_ROOT_MATRIX = (\n    (1.0, 0.3963377774, 0.2158037573),\n    (1.0, -0.1055613458, -0.0638541728),\n    (1.0, -0.0894841775, -1.2914855480),\n)\n_LMS_TO_LINEAR_SRGB_MATRIX = (\n    (4.0767416621, -3.3077115913, 0.2309699292),\n    (-1.2684380046, 2.6097574011, -0.3413193965),\n    (-0.0041960863, -0.7034186147, 1.7076147010),\n)\n\n\ndef _require_color_tensor(color_tensor: torch.Tensor) -> torch.Tensor:\n    if color_tensor.ndim != 3 or color_tensor.shape[0] != 3:\n        raise ValueError(\"color_tensor must be a 3xHxW tensor\")\n    return color_tensor\n\n\ndef _require_reference_illuminant(reference_illuminant: str) -> str:\n    normalized = reference_illuminant.upper()\n    if normalized not in _REFERENCE_ILLUMINANTS:\n        raise ValueError(f\"Unsupported reference_illuminant: {reference_illuminant}\")\n    return normalized\n\n\ndef _full_like_spatial(reference_tensor: torch.Tensor, fill_value: float) -> torch.Tensor:\n    return torch.full(\n        reference_tensor.shape[1:], fill_value, dtype=reference_tensor.dtype, device=reference_tensor.device\n    )\n\n\ndef _degrees_from_unit_hue(unit_hue_tensor: torch.Tensor) -> torch.Tensor:\n    return torch.remainder(unit_hue_tensor * 360.0, 360.0)","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/image_util/color_conversion.py#L38-L74","documentation":"_require_color_tensor guards every color-space conversion helper: input must be a 3-D tensor with 3 channels in the first dimension (3xHxW, CHW RGB layout). Any other rank or channel layout is rejected before matrix math is applied.","triggerScenarios":"Passing an HWC tensor (shape HxWx3), a batched BCHW tensor, a grayscale 1xHxW or HxW tensor, or a 4-channel RGBA tensor into helpers like srgb_from_linear_srgb or xyz_from_srgb.","commonSituations":"Forgetting to permute a PIL/numpy image (HWC) to CHW, passing a batch dimension, loading RGBA images, working with grayscale images.","solutions":["Convert to CHW with tensor.permute(2, 0, 1) for HWC inputs","Slice RGB: tensor[:3] for RGBA, or tensor[None] for HxW grayscale","Squeeze/select the batch: tensor[0] for a 1-element BCHW batch","Validate shape before calling: assert t.ndim == 3 and t.shape[0] == 3"],"exampleFix":"// before\nsrgb_from_linear_srgb(image_np_tensor)  # HWC\n// after\nchw = torch.from_numpy(image).permute(2, 0, 1)[:3]\nsrgb_from_linear_srgb(chw)","handlingStrategy":"type-guard","validationCode":"if tensor.ndim != 3 or tensor.shape[0] != 3:\n    tensor = tensor.permute(2, 0, 1)[:3]  # HWC/RGBA -> CHW RGB","typeGuard":"def is_3xhxw(t: torch.Tensor) -> bool:\n    return isinstance(t, torch.Tensor) and t.ndim == 3 and t.shape[0] == 3","tryCatchPattern":"try:\n    out = srgb_from_linear_srgb(tensor)\nexcept ValueError as e:\n    if \"3xHxW\" in str(e):\n        tensor = tensor.permute(2, 0, 1)[:3]\n        out = srgb_from_linear_srgb(tensor)\n    else:\n        raise","preventionTips":["Standardize on CHW RGB tensors at image-loading boundaries","Convert HWC numpy/PIL images with permute(2,0,1) immediately","Drop alpha channel before color conversions"],"tags":["validation","tensor-shape","color-space"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}