open-mmlab/mmdetection · error · ValueError

kwargs value must both equal

Error message

kwargs value must both equal

What it means

BaseTracker.update expects every per-object kwarg (labels, scores, frame_ids, etc.) to have length equal to num_objs (the number of detected boxes). If any tensor/list passed via kwargs has a different length, it raises ValueError.

Source

Thrown at mmdet/models/trackers/base_tracker.py:81

        for item in rm_items:
            kwargs.pop(item)
        if not hasattr(self, 'memo_items'):
            self.memo_items = memo_items
        else:
            assert memo_items == self.memo_items

        assert 'ids' in memo_items
        num_objs = len(kwargs['ids'])
        id_indice = memo_items.index('ids')
        assert 'frame_ids' in memo_items
        frame_id = int(kwargs['frame_ids'])
        if isinstance(kwargs['frame_ids'], int):
            kwargs['frame_ids'] = torch.tensor([kwargs['frame_ids']] *
                                               num_objs)
        # cur_frame_id = int(kwargs['frame_ids'][0])
        for k, v in kwargs.items():
            if len(v) != num_objs:
                raise ValueError('kwargs value must both equal')

        for obj in zip(*kwargs.values()):
            id = int(obj[id_indice])
            if id in self.tracks:
                self.update_track(id, obj)
            else:
                self.init_track(id, obj)

        self.pop_invalid_tracks(frame_id)

    def pop_invalid_tracks(self, frame_id: int) -> None:
        """Pop out invalid tracks."""
        invalid_ids = []
        for k, v in self.tracks.items():
            if frame_id - v['frame_ids'][-1] >= self.num_frames_retain:
                invalid_ids.append(k)
        for invalid_id in invalid_ids:
            self.tracks.pop(invalid_id)

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Make all per-object fields in the track results dict the same length as preds (num_objs)
  2. If you pre-filter detections, apply identical filtering to labels/scores/frame_ids
  3. When calling update manually, ensure frame_ids broadcasts to num_objs (int or tensor of that length)

Example fix

# before
results = dict(det_labels=labels, det_scores=scores[:10])  # truncated
# after
results = dict(det_labels=labels[:10], det_scores=scores[:10])
Defensive patterns

Strategy: validation

Validate before calling

n = preds.shape[0]
assert all(len(v) == n for v in kwargs.values() if hasattr(v, '__len__')), \
    'all per-object fields must match num_objs'

Prevention

When it happens

Trigger: Calling tracker.update(data, results) with a custom head whose predict returns fields of mismatched length — e.g. det_labels of length N but scores of length M != N — or passing frame_ids already as a tensor of wrong length while num_objs comes from preds.

Common situations: Writing a custom video detector/tracking head, or filtering predictions inconsistently (filter by score on one field but not others) before calling the tracker.

Related errors


AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27). Data as JSON: /api/errors/6b0fcebc573dc53b. Report an issue: GitHub.