roboflow/supervision · error · ValueError
All metadata dictionaries must have the same keys to merge.
Error message
All metadata dictionaries must have the same keys to merge.
What it means
Raised by merge_metadata when concatenating Detections objects whose metadata dictionaries do not carry exactly the same set of keys. Metadata (e.g. video_id, source_path) must be homogeneous across all Detections being merged, because the merge cannot decide what value to use for a key that is missing in some inputs.
Source
Thrown at src/supervision/detection/utils/internal.py:624
Warning: Assumes that empty detections were filtered-out before passing metadata to
this function.
Args:
metadata_list: A list of metadata dictionaries to merge.
Returns:
A single merged metadata dictionary.
Raises:
ValueError: If there are conflicting values for the same key or if
dictionaries have different keys.
"""
if not metadata_list:
return {}
all_keys_sets = [set(metadata.keys()) for metadata in metadata_list]
if not all(keys_set == all_keys_sets[0] for keys_set in all_keys_sets):
raise ValueError("All metadata dictionaries must have the same keys to merge.")
merged_metadata: _MetadataType = {}
for metadata in metadata_list:
for key, value in metadata.items():
if key not in merged_metadata:
merged_metadata[key] = value
continue
other_value = merged_metadata[key]
if isinstance(value, np.ndarray) and isinstance(other_value, np.ndarray):
if not np.array_equal(merged_metadata[key], value):
raise ValueError(
f"Conflicting metadata for key: '{key}': "
f"{type(value)}, {type(other_value)}."
)
elif isinstance(value, np.ndarray) or isinstance(other_value, np.ndarray):
# Since [] == np.array([]).
raise ValueError(View on GitHub (pinned to 7f254d9784)
Solutions
- Make every Detections carry the identical metadata keys, filling missing ones with a default (e.g. metadata={'video_id': d.metadata.get('video_id', -1)}) before merging
- If the keys are intentionally different, strip metadata (rebuild Detections with metadata={}) before concatenating
- Union the keys explicitly per input and fill defaults in your own pre-merge step so the library invariant (all_keys_sets equal) holds
Example fix
// before
merged = sv.Detections.merge([d1, d2]) # d1.metadata={'video_id':0}, d2.metadata={}
// after
keys = d1.metadata.keys() | d2.metadata.keys()
d1.metadata = {k: d1.metadata.get(k, None) for k in keys}
d2.metadata = {k: d2.metadata.get(k, None) for k in keys}
merged = sv.Detections.merge([d1, d2]) Defensive patterns
Strategy: validation
Validate before calling
def assert_mergeable_metadata(detections_list):
key_sets = [set(d.metadata.keys()) for d in detections_list]
first = key_sets[0]
for d, ks in zip(detections_list, key_sets):
assert ks == first, f"metadata keys differ: {ks} vs {first} (obj {d})" Try / catch
try:
merged = sv.Detections.merge(detections_list)
except ValueError as e:
if "same keys to merge" in str(e):
keys = set().union(*(d.metadata.keys() for d in detections_list))
for d in detections_list:
d.metadata = {k: d.metadata.get(k, None) for k in keys}
merged = sv.Detections.merge(detections_list)
else:
raise Prevention
- Always populate metadata with a fixed schema (same keys, default None) at Detections construction sites
- Write a small merge_detections wrapper that normalizes metadata keys and values before calling sv.Detections.merge
- Add a unit test that merges two Detections built by different connectors to catch schema drift
When it happens
Trigger: Detections.merge([...]) or Detections.concatenate([...]) (core.py:2495), Detections.__add__ path, merge of two single-detection Detections (core.py:3462), or annotations.merge() (core.py:3366) where one Detections was built with metadata={'video_id': 1} and another with metadata={} or a differently-keyed dict.
Common situations: Concatenating per-frame Detections in a loop where some frames got metadata and others did not; merging detections from two different models/pipelines that attach different metadata keys; incrementally adding a new metadata key to an existing pipeline while old pickled/cached Detections lack it.
Related errors
- Both Detections should have exactly 1 detected object.
- Field '{attribute}' should be consistently None or not None
- All data values within a single object must have equal lengt
- Conflicting metadata for key: '{key}': {type(value)}, {type(
- Conflicting metadata for key: '{key}'.
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/b25ceb024f88c0cb.
Report an issue: GitHub.