roboflow/supervision · error · ValueError

All data dictionaries must have the same keys to merge.

Error message

All data dictionaries must have the same keys to merge.

What it means

The internal data-merge helper (used when concatenating/merging Detections objects) requires every Detections' data dict to have exactly the same key set, because each key's values are stacked column-wise across the objects. Heterogeneous keys (one Detections carrying 'class_name' that another lacks) would leave holes in the aligned arrays, so it fails fast.

Source

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

    Args:
        data_list: The data payloads of the Detections instances. Each data payload
            is a dictionary with the same keys, and the values are either lists or
            npt.NDArray[np.generic].

    Returns:
        A single data payload containing the merged data, preserving the original data
            types (list or npt.NDArray[np.generic]).

    Raises:
        ValueError: If data values within a single object have different lengths or if
            dictionaries have different keys.
    """
    if not data_list:
        return {}

    all_keys_sets = [set(data.keys()) for data in data_list]
    if not all(keys_set == all_keys_sets[0] for keys_set in all_keys_sets):
        raise ValueError("All data dictionaries must have the same keys to merge.")

    for data in data_list:
        lengths = [len(value) for value in data.values()]
        if len(set(lengths)) > 1:
            raise ValueError(
                "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

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Normalize keys before merging: add the missing key to each Detections with a placeholder aligned array (e.g. np.array([''] * len(d))).
  2. Drop the extra keys from the richer Detections so all share the minimal common set you need.
  3. Ensure every construction path in your pipeline populates the same data keys (centralize in a helper).

Example fix

# before
 merged = sv.Detections.merge([d_with_names, d_without_names])

# after
 key = sv.CLASS_NAME_DATA_FIELD
 if key not in d_without_names.data:
     d_without_names.data[key] = np.array([""] * len(d_without_names), dtype=object)
 merged = sv.Detections.merge([d_with_names, d_without_names])
Defensive patterns

Strategy: validation

Validate before calling

all_keys = [set(d.data.keys()) for d in detections_list]
if len({frozenset(k) for k in all_keys}) != 1:
    raise ValueError(f"Mismatched data keys before merge: {all_keys}")
merged = sv.Detections.merge(detections_list)

Type guard

def have_same_data_keys(detections_list: list[sv.Detections]) -> bool:
    key_sets = {frozenset(d.data.keys()) for d in detections_list}
    return len(key_sets) <= 1

Try / catch

try:
    merged = sv.Detections.merge(detections_list)
except ValueError as e:
    logger.warning("Merge blocked by data-key mismatch: %s", e)
    common = set.intersection(*[set(d.data) for d in detections_list])
    for d in detections_list:
        for k in list(d.data):
            if k not in common:
                del d.data[k]
    merged = sv.Detections.merge(detections_list)

Prevention

When it happens

Trigger: sv.Detections.merge([d1, d2]) where d1 has data={CLASS_NAME_DATA_FIELD: ...} and d2 has data={}; or concatenate() where one branch added tracker/confidence metadata keys (e.g. from ByteTrack) and another branch was constructed raw.

Common situations: Mixing tracker-annotated Detections with freshly constructed ones; one code path enriching data with custom keys and another not; filtering/empty Detections losing keys then being merged back in.

Related errors


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