Comfy-Org/ComfyUI · error · ValueError

batch_index {batch_index} out of range; moge_geometry has ba

Error message

batch_index {batch_index} out of range; moge_geometry has batch size {B}.

What it means

The mesh node exports one batch element at a time; batch_index must be < points.shape[0]. An index equal to or above the geometry's batch size is rejected (note the lower bound is not re-checked here because the input widget already enforces min=0).

Source

Thrown at comfy_extras/nodes_moge.py:364

                                     "differ, so batches can't be stacked into a single MESH."),
                io.Int.Input("decimation", default=1, min=1, max=8,
                             tooltip="Vertex stride; 1 = full resolution."),
                io.Float.Input("discontinuity_threshold", default=0.04, min=0.0, max=1.0, step=0.01,
                               tooltip="Drop pixels whose 3x3 depth span exceeds this fraction. 0 = off."),
                io.Boolean.Input("texture", default=True,
                                 tooltip="Carry the source image through as the baseColor texture."),
            ],
            outputs=[io.Mesh.Output()],
        )

    @classmethod
    def execute(cls, moge_geometry, batch_index, decimation, discontinuity_threshold, texture) -> io.NodeOutput:
        if "points" not in moge_geometry:
            raise ValueError("moge_geometry has no points output.")
        points = moge_geometry["points"]
        B = points.shape[0]
        if batch_index >= B:
            raise ValueError(f"batch_index {batch_index} out of range; moge_geometry has batch size {B}.")

        # Pass depth so the rtol edge check sees radial depth -- for panoramas
        # points[..., 2] = cos(phi)*r goes negative below the equator and the rtol clamp would drop the bottom half.
        edge_depth = moge_geometry["depth"][batch_index] if "depth" in moge_geometry else None
        verts, faces, uvs = triangulate_grid_mesh(
            points[batch_index], decimation=decimation,
            discontinuity_threshold=discontinuity_threshold, depth=edge_depth,
        )
        if verts.shape[0] == 0 or faces.shape[0] == 0:
            raise ValueError("MoGe produced an empty mesh; try discontinuity_threshold=0 or apply_mask=False.")

        if "intrinsics" not in moge_geometry:
            # Panorama: rotate MoGe spherical (Z up) -> glTF (Y up, Z back), correct for inside-the-sphere viewing)
            verts = verts[:, [1, 2, 0]].contiguous()
        else:
            # Perspective MoGe (X right, Y down, Z forward) -> glTF; face flip keeps winding CCW after the Y/Z flip.
            verts = verts * torch.tensor([1.0, -1.0, -1.0], dtype=verts.dtype)
            faces = faces[:, [0, 2, 1]].contiguous()

View on GitHub (pinned to 1c6d8d45b3)

Solutions

  1. Set batch_index to a value in [0, B-1]; check B via points.shape[0].
  2. For batched inputs, loop over indices or insert a batch-split node before meshing.
  3. Reset the widget value to 0 when switching to single-image geometry.
Defensive patterns

Strategy: validation

Validate before calling

B = moge_geometry['points'].shape[0]
if not 0 <= batch_index < B:
    raise UserFacingError(f'batch_index must be in [0, {B - 1}]')

Prevention

When it happens

Trigger: batch_index >= B, e.g. batch_index=1 on a single-image geometry, or a stale index after switching from a multi-image batch to a single image upstream.

Common situations: Workflows with a fixed batch_index from a batched run later fed single images; UI widgets remembering a previous higher index.

Related errors


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