{"record":{"id":"105972a5fb1229c3","repo":"open-mmlab/mmdetection","slug":"new-classes-new-classes-is-not-a-subset-of-class","errorCode":null,"errorMessage":"new classes {new_classes} is not a subset of classes {old_classes} in METAINFO.","messagePattern":"new classes (.+?) is not a subset of classes (.+?) in METAINFO\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mmdet/datasets/base_semseg_dataset.py","lineNumber":169,"sourceCode":"        is not equal to new classes in self._metainfo and nether of them is not\n        None, `label_map` is not None.\n\n        Args:\n            new_classes (list, tuple, optional): The new classes name from\n                metainfo. Default to None.\n\n\n        Returns:\n            dict, optional: The mapping from old classes in cls.METAINFO to\n                new classes in self._metainfo\n        \"\"\"\n        old_classes = cls.METAINFO.get('classes', None)\n        if (new_classes is not None and old_classes is not None\n                and list(new_classes) != list(old_classes)):\n\n            label_map = {}\n            if not set(new_classes).issubset(cls.METAINFO['classes']):\n                raise ValueError(\n                    f'new classes {new_classes} is not a '\n                    f'subset of classes {old_classes} in METAINFO.')\n            for i, c in enumerate(old_classes):\n                if c not in new_classes:\n                    # 0 is background\n                    label_map[i] = 0\n                else:\n                    label_map[i] = new_classes.index(c)\n            return label_map\n        else:\n            return None\n\n    def _update_palette(self) -> list:\n        \"\"\"Update palette after loading metainfo.\n\n        If length of palette is equal to classes, just return the palette.\n        If palette is not defined, it will randomly generate a palette.\n        If classes is updated by customer, it will return the subset of","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/open-mmlab/mmdetection/blob/cfd5d3a985b0249de009b67d04f37263e11cdf3d/mmdet/datasets/base_semseg_dataset.py#L151-L187","documentation":"BaseSemanticSegmentationDataset.get_label_map builds a mapping when the user-supplied metainfo['classes'] differs from the dataset class's default METAINFO['classes']. The new classes must be a subset of the original classes; otherwise (renamed or entirely new labels) it raises this ValueError. The mapping only supports dropping/reordering existing classes and mapping dropped ones to background (0).","triggerScenarios":"Passing metainfo=dict(classes=[...]) to a semseg dataset where the list contains class names absent from the class's METAINFO['classes'], e.g. custom names for a model fine-tuned on a different label taxonomy, or reordered-with-renames.","commonSituations":"Fine-tuning a semseg model on a subset of ADE20K/Cityscapes but changing label spellings; loading a custom dataset by extending a built-in class; case mismatches ('Road' vs 'road').","solutions":["Use exactly the original class names (copy spelling/case from the dataset class METAINFO) and only drop entries to define your subset","If you need genuinely new classes, subclass the dataset and override METAINFO = dict(classes=(...)) instead of passing metainfo at construction","Check for typos/case differences between your classes list and METAINFO['classes'] programmatically before constructing"],"exampleFix":"# before\nds = CityscapesDataset(\n  data_root='data/', data_prefix=dict(img_path='leftImg8bit', seg_map_path='gtFine'),\n  metainfo=dict(classes=['road', 'sidewalk', 'vehicle']))  # 'vehicle' not in METAINFO\n# after\nfrom mmdet.datasets import CityscapesDataset\n# option A: subset with exact names\nds = CityscapesDataset(..., metainfo=dict(classes=['road', 'sidewalk', 'car']))\n# option B: new taxonomy -> subclass\nclass MyDataset(CityscapesDataset):\n  METAINFO = dict(classes=('road', 'sidewalk', 'vehicle'))\nds = MyDataset(...)","handlingStrategy":"validation","validationCode":"import inspect\nds_cls = CocoDataset  # whatever class you use\nold = list(ds_cls.METAINFO['classes'])\nnew = my_classes\nunknown = set(map(str, new)) - set(map(str, old))\nassert not unknown, f'classes not in METAINFO (typo/subset violation): {sorted(unknown)}'","typeGuard":"def is_valid_class_subset(cls, new_classes) -> bool:\n    old = list(cls.METAINFO.get('classes') or [])\n    return set(map(str, new_classes)).issubset(set(map(str, old)))","tryCatchPattern":"try:\n    ds = DatasetClass(..., metainfo=dict(classes=my_classes))\nexcept ValueError as e:\n    if 'not a subset of classes' in str(e):\n        raise SystemExit(f'Fix class names {my_classes} to match METAINFO {cls.METAINFO[\"classes\"]} or subclass with new METAINFO')\n    raise","preventionTips":["Copy class names verbatim from the dataset class source or METAINFO","For new taxonomies, subclass and override METAINFO instead of metainfo at init","Diff your classes list against METAINFO['classes'] in a unit test, catching case/whitespace mismatches"],"tags":["mmdetection","semantic-segmentation","dataset","metainfo","classes"],"backgroundTag":"label-mismatch","analyzedSha":"cfd5d3a985b0249de009b67d04f37263e11cdf3d","analyzedAt":"2026-08-27T20:54:20.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}