{"record":{"id":"50ebc8edffe81beb","repo":"roboflow/supervision","slug":"the-keys-of-the-images-and-annotations-dictionarie","errorCode":null,"errorMessage":"The keys of the images and annotations dictionaries must match.","messagePattern":"The keys of the images and annotations dictionaries must match\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/core.py","lineNumber":101,"sourceCode":"            be removed in ``0.33.0``; use a list of paths instead.\n            When a list of paths is provided, images are loaded lazily on\n            demand, which is more memory-efficient.\n        annotations: Dictionary mapping\n            image path to annotations. The dictionary keys match\n            match the keys in `images` or entries in the list of\n            image paths.\n    \"\"\"\n\n    def __init__(\n        self,\n        classes: list[str],\n        images: list[str] | dict[str, npt.NDArray[np.uint8]],\n        annotations: dict[str, Detections],\n    ) -> None:\n        self.classes = classes\n\n        if set(images) != set(annotations):\n            raise ValueError(\n                \"The keys of the images and annotations dictionaries must match.\"\n            )\n        self.annotations = {\n            image_path: deepcopy(annotation)\n            for image_path, annotation in annotations.items()\n        }\n\n        np_classes = np.array(self.classes)\n        for image_path, annotation in self.annotations.items():\n            class_ids = annotation.class_id\n            if class_ids is None:\n                continue\n            if not np.issubdtype(class_ids.dtype, np.integer):\n                raise ValueError(\n                    f\"Detection annotation for image {image_path!r} contains \"\n                    f\"non-integer class_id values with dtype {class_ids.dtype}.\"\n                )\n","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/core.py#L83-L119","documentation":"Raised by the DetectionDataset constructor when the set of image keys does not equal the set of annotation keys. Every image must have exactly one Detections annotation and vice versa; a mismatch means the dataset would have images without labels or labels pointing at nonexistent images.","triggerScenarios":"Calling DetectionDataset(classes=..., images={'a.jpg': img}, annotations={'b.jpg': dets}) — key 'a.jpg' vs 'b.jpg'. Also when passing images as a list while the annotations dict keys don't exactly match the list entries (set comparison still applies).","commonSituations":"Building a dataset from globbed image files and a parsed annotations dict where some images failed to parse or some annotation files have no matching image; off-by-one filename differences ('.jpeg' vs '.jpg'); leading './' in one set but not the other.","solutions":["Intersect the two key sets before constructing: keep = set(images) & set(annotations), then filter both.","Normalize paths (same suffix, same prefix, os.path.normpath) so keys compare equal.","Log the symmetric difference set(images) ^ set(annotations) to see exactly which keys mismatch."],"exampleFix":"// before\nimages = {p: cv2.imread(p) for p in glob('images/*')}\nds = DetectionDataset(classes=c, images=images, annotations=anns)  # key mismatch\n\n// after\nkeep = sorted(set(images) & set(anns))\nds = DetectionDataset(classes=c, images=[p for p in keep], annotations={p: anns[p] for p in keep})","handlingStrategy":"validation","validationCode":"if set(images) != set(annotations):\n    keep = set(images) & set(annotations)\n    missing = set(images) ^ set(annotations)\n    print(f\"Skipping unmatched entries: {missing}\")\n    images = {p: images[p] for p in images if p in keep} if isinstance(images, dict) else [p for p in images if p in keep]\n    annotations = {p: annotations[p] for p in annotations if p in keep}\nds = DetectionDataset(classes=classes, images=images, annotations=annotations)","typeGuard":"def keys_match(images, annotations: dict) -> bool:\n    return set(images) == set(annotations)","tryCatchPattern":null,"preventionTips":["Derive annotations and images from one source of truth (one glob loop).","Normalize paths (abspath, same extension casing) before building the dicts.","Log the symmetric difference of key sets during dataset construction debugging."],"tags":["dataset","constructor","key-mismatch","validation"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}