roboflow/supervision · error · ValueError

Unexpected array dimension for key '{key}'.

Error message

Unexpected array dimension for key '{key}'.

What it means

Raised by merge_data when a data value is an np.ndarray with ndim == 0 (a scalar array). The merge logic only defines hstack for 1-D and vstack for n-D arrays; a 0-d array fits neither, so it is rejected as an unexpected dimension.

Source

Thrown at src/supervision/detection/utils/internal.py:589

                "All data values within a single object must have equal length."
            )

    merged_data: dict[str, Any] = {key: [] for key in all_keys_sets[0]}
    for data in data_list:
        for key in data:
            merged_data[key].append(data[key])

    for key in merged_data:
        if all(isinstance(item, list) for item in merged_data[key]):
            merged_data[key] = list(chain.from_iterable(merged_data[key]))
        elif all(isinstance(item, np.ndarray) for item in merged_data[key]):
            ndim = merged_data[key][0].ndim
            if ndim == 1:
                merged_data[key] = np.hstack(merged_data[key])
            elif ndim > 1:
                merged_data[key] = np.vstack(merged_data[key])
            else:
                raise ValueError(f"Unexpected array dimension for key '{key}'.")
        else:
            raise ValueError(
                f"Inconsistent data types for key '{key}'. Only np.ndarray and list "
                f"types are allowed."
            )

    return cast(_DetectionDataType, merged_data)


def merge_metadata(metadata_list: list[_MetadataType]) -> _MetadataType:
    """
    Merge metadata from a list of metadata dictionaries.

    This function combines the metadata dictionaries. If a key appears in more than one
    dictionary, the values must be identical for the merge to succeed.

    Warning: Assumes that empty detections were filtered-out before passing metadata to
    this function.

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Store per-detection values as 1-D arrays: np.full(len(detections), 42) or np.asarray([42]*len(detections))
  2. Move true per-object scalars into Detections.metadata instead of data
  3. Validate ndim >= 1 and length == len(xyxy) for every data value before merge

Example fix

# before
d.data['frame_id'] = np.asarray(42)  # 0-d
merged = sv.Detections.merge([d, other])
# after
d.data['frame_id'] = np.full(len(d), 42)  # 1-D, aligned
merged = sv.Detections.merge([d, other])
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def assert_data_shapes_mergeable(detections_list):
    for d in detections_list:
        n = len(d.xyxy)
        for k, v in d.data.items():
            arr = np.asarray(v)
            assert arr.ndim >= 1 and len(arr) == n, f"data['{k}'] bad shape {arr.shape} for {n} detections"

Prevention

When it happens

Trigger: sv.Detections.merge([d1, ...]) where some input's data value is np.asarray(scalar), e.g. d.data['frame_id'] = np.asarray(42) or np.float64(0.5). Such a value is also misaligned with xyxy (one scalar for N detections) and would fail length checks first if N > 1.

Common situations: Wrapping scalar per-object values with np.asarray when populating data, producing 0-d arrays; storing np.float64/np.int64 scalars (which are 0-d array-likes) in data; migrating a metadata-style value into data without reshaping to per-detection shape.

Related errors


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