roboflow/supervision · error · ValueError

Could not aggregate images shape - provided unknown mode: {m

Error message

Could not aggregate images shape - provided unknown mode: {mode}. Supported modes: {list(SHAPE_AGGREGATION_FUN.keys())}.

What it means

Raised when `tile_scaling` (the mode used to aggregate image shapes into a single tile size) is not one of 'min', 'max', 'avg'. The dispatch is a literal dict lookup (`SHAPE_AGGREGATION_FUN`), so any other string — including case variants — is rejected. The error message lists the supported modes.

Source

Thrown at src/supervision/utils/image.py:920

    images: list[npt.NDArray[np.uint8]], aggregator: Callable[[list[int]], float]
) -> tuple[int, int]:
    height = round(aggregator([i.shape[0] for i in images]))
    width = round(aggregator([i.shape[1] for i in images]))
    return width, height


SHAPE_AGGREGATION_FUN = {
    "min": partial(_calculate_aggregated_images_shape, aggregator=np.min),
    "max": partial(_calculate_aggregated_images_shape, aggregator=np.max),
    "avg": partial(_calculate_aggregated_images_shape, aggregator=np.average),
}


def _aggregate_images_shape(
    images: list[npt.NDArray[np.uint8]], mode: Literal["min", "max", "avg"]
) -> tuple[int, int]:
    if mode not in SHAPE_AGGREGATION_FUN:
        raise ValueError(
            f"Could not aggregate images shape - provided unknown mode: {mode}. "
            f"Supported modes: {list(SHAPE_AGGREGATION_FUN.keys())}."
        )
    return SHAPE_AGGREGATION_FUN[mode](images)


def _establish_grid_size(
    images: list[npt.NDArray[np.uint8]],
    grid_size: tuple[int | None, int | None] | None,
) -> tuple[int, int]:
    if grid_size is None or all(e is None for e in grid_size):
        return _negotiate_grid_size(images=images)
    if grid_size[0] is None:
        columns = grid_size[1]
        assert columns is not None
        return math.ceil(len(images) / columns), columns
    if grid_size[1] is None:
        rows = grid_size[0]

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Use one of exactly: 'min', 'max', 'avg'.
  2. Normalize CLI input: `mode = mode.strip().lower()` and reject unknown values with the supported list.
  3. If 'mean' was intended, use 'avg'.

Example fix

# before
montage = sv.create_tiles(images=images, tile_scaling='mean')
# after
montage = sv.create_tiles(images=images, tile_scaling='avg')
Defensive patterns

Strategy: validation

Validate before calling

assert tile_scaling in {'min', 'max', 'avg'}, f'unknown tile_scaling: {tile_scaling}'

Type guard

from typing import Literal
TileScaling = Literal['min', 'max', 'avg']

def is_valid_tile_scaling(mode: str) -> bool:
    return mode in {'min', 'max', 'avg'}

Prevention

When it happens

Trigger: Passing `tile_scaling='average'`, `'MIN'`, or `'mean'` to `sv.create_tiles`; passing a typo like 'maxi'; forwarding a user-supplied string from a CLI without validation.

Common situations: CLI/config options accepting free text; users assuming 'mean' is valid since it is a common numpy aggregator; case-sensitive values from YAML configs.

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/0eb095223cff52c8. Report an issue: GitHub.