roboflow/supervision · error · ValueError

Inconsistent data types for key '{key}'. Only np.ndarray and

Error message

Inconsistent data types for key '{key}'. Only np.ndarray and list types are allowed.

What it means

Raised by merge_data when, for one data key, the values coming from different Detections objects are neither all Python lists nor all np.ndarrays. The merge can only flatten lists with chain or stack arrays with hstack/vstack, so mixed container types for the same key are rejected.

Source

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

    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.

    Args:

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Normalize the type of every data value to np.ndarray across all inputs before merging (e.g. d.data['key'] = np.asarray(d.data['key']))
  2. If the value is a scalar per detection, wrap it as a 1-element-per-detection list or array aligned with xyxy
  3. Use consistent data-field construction everywhere: always np.asarray when populating detections.data

Example fix

# before
merged = sv.Detections.merge([d_list_version, d_array_version])
# after
for d in detections_list:
    for k, v in d.data.items():
        if not isinstance(v, np.ndarray):
            d.data[k] = np.asarray(v)
merged = sv.Detections.merge(detections_list)
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def normalize_data_types(detections_list):
    for d in detections_list:
        for k, v in d.data.items():
            if not isinstance(v, np.ndarray):
                d.data[k] = np.asarray(v)
    return detections_list

Prevention

When it happens

Trigger: sv.Detections.merge([d1, d2]) where d1.data['key'] is a list and d2.data['key'] is an np.ndarray (or any other type like a tuple/str/int). Also raised when the value is a plain scalar type that is neither list nor ndarray in any input.

Common situations: One pipeline step stores data values as Python lists (common in custom code) while a library connector stores the same key as np.ndarray; mixing Detections built by from_ultralytics (ndarray data) with hand-built Detections (list data) under the same key name.

Related errors


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