open-mmlab/mmdetection · warning
{self.__class__.__name__} got empty `self.results`. Please e
Error message
{self.__class__.__name__} got empty `self.results`. Please ensure that the processed results are properly added into `self.results` in `process` method. What it means
BaseVideoMetric.evaluate() warns when self.results is empty before calling collect_tracking_results. It means no per-batch results were ever appended in process(), so evaluation has nothing to compute and will return empty/failed metrics. This is a warning, not an exception, but evaluation output will be meaningless.
Source
Thrown at mmdet/evaluation/metrics/base_video_metric.py:62
# video process
self.process_video(video_data_samples)
else:
# image process
self.process_image(video_data_samples, ori_video_len)
def evaluate(self, size: int = 1) -> dict:
"""Evaluate the model performance of the whole dataset after processing
all batches.
Args:
size (int): Length of the entire validation dataset.
Returns:
dict: Evaluation metrics dict on the val dataset. The keys are the
names of the metrics, and the values are corresponding results.
"""
if len(self.results) == 0:
warnings.warn(
f'{self.__class__.__name__} got empty `self.results`. Please '
'ensure that the processed results are properly added into '
'`self.results` in `process` method.')
results = collect_tracking_results(self.results, self.collect_device)
if is_main_process():
_metrics = self.compute_metrics(results) # type: ignore
# Add prefix to metric names
if self.prefix:
_metrics = {
'/'.join((self.prefix, k)): v
for k, v in _metrics.items()
}
metrics = [_metrics]
else:
metrics = [None] # type: ignore
View on GitHub (pinned to cfd5d3a985)
Solutions
- Verify the validation dataloader actually yields batches (check dataset length and ann_file path)
- If you subclass BaseVideoMetric, ensure process() calls self.results.append(...) for every batch
- Check that runner.val_loop/dataloader is wired to the metric in the config so process() is invoked
- On distributed runs, confirm collect_device/gather flags so results are not lost before evaluate()
Example fix
// before
class MyVideoMetric(BaseVideoMetric):
def process(self, data_batch, data_samples):
pass # results never stored
// after
class MyVideoMetric(BaseVideoMetric):
def process(self, data_batch, data_samples):
for sample in data_samples:
self.results.append(sample.to_dict()) Defensive patterns
Strategy: validation
Validate before calling
assert len(val_dataset) > 0, 'val dataset is empty' # after one val step: assert len(metric.results) > 0, 'process() never stored results'
Prevention
- Assert the val dataloader length before running evaluation
- In custom metric subclasses, always extend self.results in process()
- Smoke-test evaluate() on a single batch before full runs
When it happens
Trigger: Calling evaluate() on a video/tracking metric (e.g. BaseVideoMetric subclass) after a validation loop in which process() never appended to self.results — e.g. the dataloader yielded no batches, process() was never called, or a custom subclass overrode process() without extending self.results.
Common situations: Empty val dataset or wrong split in the dataloader config; a custom metric subclass whose process() forgets self.results.append(...); distributed runs where results live on another rank; test pipeline mismatch so process is skipped.
Related errors
- {self.__class__.__name__} got empty `self.results`. Please e
- only {num_videos} videos loaded,but {self.world_size} gpus w
- {metric} is not in results
- metric item "{metric_item}" is not supported
- metric should be one of 'recall', 'mAP', but got {metric}.
AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27).
Data as JSON: /api/errors/48c15a83cc967ebb.
Report an issue: GitHub.