open-mmlab/mmdetection · error · ValueError
palette does not match classes as metainfo is {self._metainf
Error message
palette does not match classes as metainfo is {self._metainfo}. What it means
BaseSemanticSegmentationDataset._update_palette validates the palette against metainfo classes after label mapping. A palette longer than classes is allowed (extra entries ignored after mapping), but a palette shorter than the (mapped) number of classes raises this ValueError showing the full metainfo. Palettes can be a list of RGB tuples or an mmcv ColorStatus-like string ('random'/'none'), and list palettes must cover the classes.
Source
Thrown at mmdet/datasets/base_semseg_dataset.py:224
np.random.seed(42)
# random palette
new_palette = np.random.randint(
0, 255, size=(len(classes), 3)).tolist()
np.random.set_state(state)
elif len(palette) >= len(classes) and self.label_map is not None:
new_palette = []
# return subset of palette
for old_id, new_id in sorted(
self.label_map.items(), key=lambda x: x[1]):
# 0 is background
if new_id != 0:
new_palette.append(palette[old_id])
new_palette = type(palette)(new_palette)
elif len(palette) >= len(classes):
# Allow palette length is greater than classes.
return palette
else:
raise ValueError('palette does not match classes '
f'as metainfo is {self._metainfo}.')
return new_palette
def load_data_list(self) -> List[dict]:
"""Load annotation from directory or annotation file.
Returns:
list[dict]: All data info of dataset.
"""
data_list = []
img_dir = self.data_prefix.get('img_path', None)
ann_dir = self.data_prefix.get('seg_map_path', None)
if not osp.isdir(self.ann_file) and self.ann_file:
assert osp.isfile(self.ann_file), \
f'Failed to load `ann_file` {self.ann_file}'
lines = mmengine.list_from_file(
self.ann_file, backend_args=self.backend_args)
for line in lines:View on GitHub (pinned to cfd5d3a985)
Solutions
- Set palette='random' (or omit it) to let the dataset generate colors automatically
- Provide one RGB tuple per class: len(palette) >= len(classes) after label mapping — e.g., copy the 3-length list to the needed size or take a slice of mmcv's palette constants
- If subsetting classes, also shrink/reorder the palette to match get_label_map semantics
Example fix
# before
ds = CityscapesDataset(...,
metainfo=dict(classes=['road', 'sidewalk', 'car'],
palette=[[128, 64, 128]])) # 1 color for 3 classes
# after
ds = CityscapesDataset(...,
metainfo=dict(classes=['road', 'sidewalk', 'car'],
palette=[[128, 64, 128], [244, 35, 232], [0, 0, 142]]))
# or simply:
ds = CityscapesDataset(..., metainfo=dict(classes=[...], palette='random')) Defensive patterns
Strategy: validation
Validate before calling
n_classes = len(metainfo.get('classes', DatasetClass.METAINFO['classes']))
pal = metainfo.get('palette')
if isinstance(pal, list):
assert len(pal) >= n_classes, f'palette has {len(pal)} colors for {n_classes} classes' Type guard
def is_palette_valid(palette, n_classes) -> bool:
return not isinstance(palette, list) or len(palette) >= n_classes Try / catch
try:
ds = DatasetClass(..., metainfo=metainfo)
except ValueError as e:
if 'palette does not match classes' in str(e):
metainfo['palette'] = 'random'
ds = DatasetClass(..., metainfo=metainfo)
else:
raise Prevention
- Prefer palette='random' unless brand colors are required
- Keep palette and classes lists in one metainfo dict so they are edited together, with a paired length test
- When subsetting classes, regenerate the palette slice in the same commit
When it happens
Trigger: Passing metainfo=dict(palette=[...]) with fewer color entries than the effective number of classes, e.g., a 3-color palette against a subset of 19 Cityscapes classes, or using a palette sized for the original dataset while classes were extended.
Common situations: Custom visualization configs copied between datasets with different class counts; palette lists with off-by-one lengths; using single-tuple palettes where a list-of-tuples is required.
Related errors
- new classes {new_classes} is not a subset of classes {old_cl
- Unsupported input type: {type(single_input)}
- Invalid type for palette: {type(palette)}
- palette does not exist, random is used by default. You can a
- palette does not exist, random is used by default. You can a
AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27).
Data as JSON: /api/errors/8023f443d3954ed4.
Report an issue: GitHub.