roboflow/supervision · error · ValueError

Length of list for key '{key}' must be {n}

Error message

Length of list for key '{key}' must be {n}

What it means

Raised by supervision.validators._validate_data when a value stored in the Detections.data dict is a Python list whose length differs from n (the number of detections). Every list-valued data entry is per-detection metadata and must align row-for-row with xyxy.

Source

Thrown at src/supervision/validators/__init__.py:195

            f"tracker_id must be a 1D np.ndarray with shape {expected_shape}, but got "
            f"shape {actual_shape}"
        )


@deprecated(  # type: ignore[untyped-decorator]
    target=_validate_tracker_id,
    deprecated_in="0.29.0",
    remove_in="0.32.0",
)
def validate_tracker_id(tracker_id: Any, n: int) -> None:
    void(tracker_id, n)


def _validate_data(data: dict[str, Any], n: int) -> None:
    for key, value in data.items():
        if isinstance(value, list):
            if len(value) != n:
                raise ValueError(f"Length of list for key '{key}' must be {n}")
        elif isinstance(value, np.ndarray):
            if value.ndim == 1 and value.shape[0] != n:
                raise ValueError(f"Shape of np.ndarray for key '{key}' must be ({n},)")
            elif value.ndim > 1 and value.shape[0] != n:
                raise ValueError(
                    f"First dimension of np.ndarray for key '{key}' must have size {n}"
                )
        else:
            raise ValueError(f"Value for key '{key}' must be a list or np.ndarray")


@deprecated(  # type: ignore[untyped-decorator]
    target=_validate_data,
    deprecated_in="0.29.0",
    remove_in="0.32.0",
)
def validate_data(data: dict[str, Any], n: int) -> None:
    void(data, n)

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Match the count: repeat constants with [value] * len(detections) or np.full.
  2. Prefer np.ndarray over lists for per-detection data — same alignment rule, better vectorization.
  3. After filtering, rebuild data entries with the same index: data={k: [v[i] for i in keep]}.
  4. Use Detections.__getitem__ (det[idx]) which keeps data aligned automatically.

Example fix

# before
dets = Detections(
    xyxy=boxes,                                # 3 rows
    data={"source": ["cam1"]},                 # 1 element -> ValueError
)

# after
dets = Detections(
    xyxy=boxes,
    data={"source": np.full(len(boxes), "cam1")},
)
Defensive patterns

Strategy: validation

Validate before calling

n = len(xyxy)
data = {
    k: (v if isinstance(v, np.ndarray) else np.asarray(v))
    for k, v in data.items()
}
for k, v in data.items():
    assert v.shape[0] == n, f"data['{k}'] has {v.shape[0]} entries, expected {n}"
dets = Detections(xyxy=xyxy, data=data)

Type guard

def data_lists_aligned(data: dict[str, Any], n: int) -> bool:
    return all(
        (not isinstance(v, list)) or len(v) == n for v in data.values()
    )

Prevention

When it happens

Trigger: Constructing Detections(xyxy=boxes, data={"track_name": ["a", "b"]}) with 3 boxes; appending per-frame scalars as single-element lists for multi-detection batches.

Common situations: Storing class names, tracker labels, or annotator strings per detection; broadcasting a constant accidentally as a 1-element list; filtering detections (via indexing) which rebuilds data but manual dict construction skips the filter.

Related errors


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