Genesis-Embodied-AI/genesis-world · error · IndexError

Only one ellipsis (...) is allowed

Error message

Only one ellipsis (...) is allowed

What it means

get_indexed_shape (used by assign_indexed_tensor for scatter-style indexed writes) computes the output shape of an indexing expression. Like NumPy indexing, it expands a single Ellipsis into the full slices needed to cover the tensor's ndim, but two or more Ellipses in one index tuple are ambiguous and rejected with IndexError. This mirrors torch/NumPy semantics: 'Only one ellipsis (or ':') is allowed'.

Source

Thrown at genesis/utils/misc.py:1097

    is_preallocated = tensor is not None
    if is_preallocated or not skip_allocation:
        expected_shape = [*map(len, indices_), *expected_shape[len(indices_) :]]
        tensor = broadcast_tensor(tensor, dtype, expected_shape, dim_names).contiguous()

    return tensor, tuple(indices_)


def get_indexed_shape(tensor_shape, indices):
    """Compute the resulting shape after advanced indexing without performing the operation."""
    ndim = len(tensor_shape)

    # Expand ellipsis if present
    ellipsis_count = sum(1 for idx in indices if idx is Ellipsis)
    if ellipsis_count == 1:
        idx = indices.index(Ellipsis)
        indices = (*indices[:idx], *(slice(None),) * (ndim - len(indices) + 1), *indices[idx + 1 :])
    elif ellipsis_count > 1:
        raise IndexError("Only one ellipsis (...) is allowed")

    # Compute the broadcasted shape of all tensor indices
    broadcast_shape = torch.broadcast_shapes(*[idx.shape for idx in indices if isinstance(idx, torch.Tensor)])

    # Build output shape
    output_shape = []
    curr_idx = 0
    inserted_broadcast = False
    for idx in indices:
        if isinstance(idx, int):
            curr_idx += 1
        elif isinstance(idx, slice):
            start, stop, step = idx.indices(tensor_shape[curr_idx])
            if step > 0:
                size = max(0, (stop - start + step - 1) // step)
            else:
                size = max(0, (stop - start + step + 1) // step)
            output_shape.append(size)

View on GitHub (pinned to 56e4aa5d82)

Solutions

  1. Keep exactly one Ellipsis in the index tuple; replace the redundant one with slice(None) or drop it.
  2. When concatenating index tuples dynamically, filter to at most one Ellipsis: keep the first and expand/remove the rest.
  3. Prefer explicit slice(None) in generated code paths where an Ellipsis might already be present upstream.

Example fix

# before
assign_indexed_tensor(dst, src, (Ellipsis, mask, Ellipsis))
# after
assign_indexed_tensor(dst, src, (Ellipsis, mask))
Defensive patterns

Strategy: validation

Validate before calling

assert sum(1 for i in indices if i is Ellipsis) <= 1, 'multiple Ellipsis in index tuple'

Prevention

When it happens

Trigger: Calling torch-style advanced indexing helpers (get_indexed_shape / assign_indexed_tensor) with an indices tuple containing Ellipsis twice, e.g. (Ellipsis, 0, Ellipsis) or building indices dynamically where a default Ellipsis is appended to a tuple that already contains one.

Common situations: Programmatically constructing index tuples (e.g. (env_idx, Ellipsis) plus a user-supplied suffix that itself contains ...), or refactoring code from explicit slicing into Ellipsis-based slicing and leaving a duplicate. Rare with hand-written literal indices since two ellipses are visually obvious.

Related errors


AI-assisted analysis of Genesis-Embodied-AI/genesis-world@56e4aa5d82 (2026-08-28). Data as JSON: /api/errors/7781d2747b3bd3f7. Report an issue: GitHub.