Comfy-Org/ComfyUI · error · ValueError

moge_geometry has neither normals nor points to derive norma

Error message

moge_geometry has neither normals nor points to derive normals from.

What it means

For normal rendering, the node needs either a precomputed 'normal' tensor or a 'points' cloud to derive normals from. If moge_geometry contains neither key, normal generation is impossible and the node reports which inputs are missing.

Source

Thrown at comfy_extras/nodes_moge.py:299

        )

    @classmethod
    def execute(cls, moge_geometry, output) -> io.NodeOutput:
        is_normal = output in ("normal_directx", "normal_opengl")
        opengl = output.endswith("_opengl")

        # Pick the input tensor for the chosen mode and validate availability.
        if output in ("depth", "depth_colored"):
            if "depth" not in moge_geometry:
                raise ValueError("moge_geometry has no depth output.")
            src = moge_geometry["depth"]
        elif is_normal:
            if "normal" in moge_geometry:
                src = moge_geometry["normal"]
            elif "points" in moge_geometry:
                src = moge_geometry["points"]
            else:
                raise ValueError("moge_geometry has neither normals nor points to derive normals from.")
        elif output == "mask":
            if "mask" not in moge_geometry:
                raise ValueError("moge_geometry has no mask output.")
            src = moge_geometry["mask"]
        else:
            raise ValueError(f"Unknown output mode: {output}")

        B = src.shape[0]
        pbar = comfy.utils.ProgressBar(B)
        out: list[torch.Tensor] = []
        with tqdm(total=B, desc=f"MoGe render: {output}") as tq:
            for i in range(B):
                slc = src[i:i + 1].float()
                if output in ("depth", "depth_colored"):
                    d = _normalize_disparity(slc)
                    out.append(_turbo(d) if output == "depth_colored"
                               else d.unsqueeze(-1).expand(*d.shape, 3).contiguous())
                elif is_normal:

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Re-run inference with points or normals enabled in the geometry output.
  2. Render a mode the geometry supports (depth, mask) instead of normals.
  3. Pre-check: any(k in moge_geometry for k in ('normal', 'points')) before choosing a normal mode.
Defensive patterns

Strategy: validation

Validate before calling

if output.startswith('normal') and not ({'normal', 'points'} & set(moge_geometry)):
    raise UserFacingError('geometry lacks normals and points')

Type guard

def can_render_normals(geo) -> bool:
    return 'normal' in geo or 'points' in geo

Prevention

When it happens

Trigger: output='normal_directx' or 'normal_opengl' on a geometry dict produced by an inference mode that stored only depth/mask.

Common situations: Depth-only MoGe runs feeding a normals renderer; downstream nodes assuming normals are always available.

Related errors


AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14). Data as JSON: /api/errors/777acb7d1502ab84. Report an issue: GitHub.