Comfy-Org/ComfyUI · error · ValueError
Invalid affine shape: {ext.shape}
Error message
Invalid affine shape: {ext.shape} What it means
as_homogeneous() promotes camera extrinsics to 4x4 homogeneous form. It accepts only trailing shapes (...,3,4) (promotion applied) or (...,4,4) (no-op); any other trailing two dims raise ValueError with the offending shape. This is a strict contract check on pose tensors coming from dataset/loader code.
Source
Thrown at comfy/ldm/depth_anything_3/transform.py:24
import torch
import torch.nn.functional as F
# -----------------------------------------------------------------------------
# Affine 4x4 helpers
# -----------------------------------------------------------------------------
def as_homogeneous(ext: torch.Tensor) -> torch.Tensor:
"""Promote (...,3,4) extrinsics to (...,4,4) homogeneous form. No-op when the input is already ``(...,4,4)``."""
if ext.shape[-2:] == (4, 4):
return ext
if ext.shape[-2:] == (3, 4):
ones = torch.zeros_like(ext[..., :1, :4])
ones[..., 0, 3] = 1.0
return torch.cat([ext, ones], dim=-2)
raise ValueError(f"Invalid affine shape: {ext.shape}")
def affine_inverse(A: torch.Tensor) -> torch.Tensor:
"""Inverse of an affine matrix ``[R|T; 0 0 0 1]``."""
R = A[..., :3, :3]
T = A[..., :3, 3:]
P = A[..., 3:, :]
return torch.cat([torch.cat([R.mT, -R.mT @ T], dim=-1), P], dim=-2)
# -----------------------------------------------------------------------------
# Quaternion <-> rotation matrix (xyzw / scalar-last)
# -----------------------------------------------------------------------------
def _sqrt_positive_part(x: torch.Tensor) -> torch.Tensor:
"""sqrt(max(0, x)) with a zero subgradient where x == 0."""
ret = torch.zeros_like(x)View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Convert your pose representation to (...,3,4) or (...,4,4) [R|t] form before calling (e.g. cat rotation matrix with translation column).
- If you have quaternions, use quat_to_mat (same module) first, then build the 3x4.
- Print ext.shape right before the call and fix whatever upstream reshape produced the wrong dims.
Example fix
# before (R only, shape (...,3,3)) E = as_homogeneous(R) # after E = as_homogeneous(torch.cat([R, t.unsqueeze(-1)], dim=-1)) # (...,3,4)
Defensive patterns
Strategy: type-guard
Validate before calling
assert ext.shape[-2:] in ((3, 4), (4, 4)), f"extrinsics must end (...,3,4) or (...,4,4), got {tuple(ext.shape)}" Type guard
def is_affine_pose_tensor(ext: "torch.Tensor") -> bool:
return ext.ndim >= 2 and ext.shape[-2:] in ((3, 4), (4, 4)) Prevention
- Standardize all pose tensors to (...,3,4) [R|t] at the dataloader boundary.
- Convert quaternion/axis-angle representations before feeding pose utilities.
- Log shapes once at ingestion so mis-formatted poses fail loudly at the source.
When it happens
Trigger: Passing extrinsics with shapes like (...,3,3) (rotation only), (...,4) (quaternion or translation vector), (...,2,4), or non-matrix tensors. Common when a dataloader returns poses in a different convention (e.g. 4x4 already transposed to column-major, or axis-angle vectors) that was not converted first.
Common situations: Feeding DA3 ray/pose utilities with raw dataset camera poses (COLMAP/world-to-camera variants, quaternion+translation format); shapes corrupted by a wrong reshape or flatten earlier in the pipeline.
Related errors
- Invalid rotation matrix shape {matrix.shape}.
- pose_method='cam_dec' requires a camera decoder, but the loa
- pose_method='ray_pose' requires a DualDPT head, but the load
- Unexpected token width: {out_x.shape[-1]}
- Unknown DINOv2 backbone variant: {backbone_name!r}
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/e641aed2c4a67e23.
Report an issue: GitHub.