{"record":{"id":"d4976e626afae685","repo":"open-mmlab/mmdetection","slug":"dataset-metainfo-must-contain-classes","errorCode":null,"errorMessage":"dataset metainfo must contain `classes`","messagePattern":"dataset metainfo must contain `classes`","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mmdet/datasets/samplers/class_aware_sampler.py","lineNumber":80,"sourceCode":"        # get number of images containing each category\n        self.num_cat_imgs = [len(x) for x in self.cat_dict.values()]\n        # filter labels without images\n        self.valid_cat_inds = [\n            i for i, length in enumerate(self.num_cat_imgs) if length != 0\n        ]\n        self.num_classes = len(self.valid_cat_inds)\n\n    def get_cat2imgs(self) -> Dict[int, list]:\n        \"\"\"Get a dict with class as key and img_ids as values.\n\n        Returns:\n            dict[int, list]: A dict of per-label image list,\n            the item of the dict indicates a label index,\n            corresponds to the image index that contains the label.\n        \"\"\"\n        classes = self.dataset.metainfo.get('classes', None)\n        if classes is None:\n            raise ValueError('dataset metainfo must contain `classes`')\n        # sort the label index\n        cat2imgs = {i: [] for i in range(len(classes))}\n        for i in range(len(self.dataset)):\n            cat_ids = set(self.dataset.get_cat_ids(i))\n            for cat in cat_ids:\n                cat2imgs[cat].append(i)\n        return cat2imgs\n\n    def __iter__(self) -> Iterator[int]:\n        # deterministically shuffle based on epoch\n        g = torch.Generator()\n        g.manual_seed(self.epoch + self.seed)\n\n        # initialize label list\n        label_iter_list = RandomCycleIter(self.valid_cat_inds, generator=g)\n        # initialize each per-label image list\n        data_iter_dict = dict()\n        for i in self.valid_cat_inds:","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/open-mmlab/mmdetection/blob/cfd5d3a985b0249de009b67d04f37263e11cdf3d/mmdet/datasets/samplers/class_aware_sampler.py#L62-L98","documentation":"ClassAwareSampler builds a category-to-image index by reading dataset.metainfo['classes']; if the wrapped dataset has no 'classes' key in its metainfo (e.g. it is a plain base dataset or a wrapper that drops metainfo), sampling cannot proceed and ValueError is raised during __init__.","triggerScenarios":"Constructing ClassAwareSampler over a dataset whose METAINFO lacks 'classes' — e.g. wrapping ConcatDataset/CustomDataset without category definitions, a video/tracking dataset, or a plain mmengine BaseDataset with no metainfo merge.","commonSituations":"Using ClassAwareSampler with a custom dataset class that forgets to define METAINFO with classes, wrapping datasets in ClassBalancedDataset (double wrapping) that hides metainfo, or version upgrades where metainfo propagation changed.","solutions":["Give the dataset a metainfo containing classes, e.g. metainfo=dict(classes=...) or define METAINFO in your dataset subclass using mmdet's CocoDetClasses","Ensure the sampler wraps the leaf detection dataset (like CocoDataset) rather than a wrapper that strips metainfo","Pass metainfo explicitly through the dataset config: dataset=dict(type='MyDataset', metainfo=dict(classes=[...]), ...)"],"exampleFix":"# before\ndataset = dict(type='MyDetDataset', ...)  # no classes in metainfo\nsampler = dict(type='ClassAwareSampler', num_sample_class=1, cls_loss_weight=1.0)\n# after\nfrom mmdet.datasets import CocoDetClasses\ndataset = dict(type='MyDetDataset', metainfo=dict(classes=CocoDetClasses), ...)","handlingStrategy":"validation","validationCode":"metainfo = dataset.metainfo\nassert 'classes' in metainfo and metainfo['classes'], 'dataset metainfo lacks classes; required by ClassAwareSampler'","typeGuard":"def has_classes_metainfo(ds) -> bool:\n    return bool(getattr(ds, 'metainfo', {}).get('classes'))","tryCatchPattern":null,"preventionTips":["Always define METAINFO (with classes) in custom detection dataset classes","Pass metainfo=dict(classes=...) explicitly when wrapping generic datasets with ClassAwareSampler"],"tags":["mmdet","sampler","class-aware","metainfo","classes"],"backgroundTag":"missing-metadata-key","analyzedSha":"cfd5d3a985b0249de009b67d04f37263e11cdf3d","analyzedAt":"2026-08-27T20:54:20.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}