{"record":{"id":"0996dd7128e8314d","repo":"roboflow/supervision","slug":"coco-annotation-file-contains-duplicate-entries-fo","errorCode":null,"errorMessage":"COCO annotation file contains duplicate entries for image {image_name}. Each image must appear at most once.","messagePattern":"COCO annotation file contains duplicate entries for image (.+?)\\. Each image must appear at most once\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/formats/coco.py","lineNumber":554,"sourceCode":"                f\"resolves to the images directory itself \"\n                f\"({images_directory_resolved}). Expected a path to an \"\n                \"image file.\"\n            )\n        if images_directory_resolved not in resolved_image_path.parents:\n            raise ValueError(\n                f\"COCO annotation refers to image {image_name!r}, which \"\n                f\"resolves to {resolved_image_path} — outside the images \"\n                f\"directory {images_directory_resolved}.\"\n            )\n        if resolved_image_path.is_dir():\n            raise ValueError(\n                f\"COCO annotation refers to image {image_name!r}, which \"\n                f\"resolves to directory {resolved_image_path}. Expected a \"\n                \"path to an image file.\"\n            )\n        image_path = str(resolved_image_path)\n        if image_path in annotations:\n            raise ValueError(\n                f\"COCO annotation file contains duplicate entries for image \"\n                f\"{image_name!r}. Each image must appear at most once.\"\n            )\n\n        with_masks = force_masks or any(\n            _with_seg_mask(annotation) for annotation in image_annotations\n        )\n        annotation = coco_annotations_to_detections(\n            image_annotations=image_annotations,\n            resolution_wh=(image_width, image_height),\n            with_masks=with_masks,\n            use_iscrowd=use_iscrowd,\n        )\n\n        annotation = map_detections_class_id(\n            source_to_target_mapping=class_index_mapping,\n            detections=annotation,\n        )","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/formats/coco.py#L536-L572","documentation":"Raised by load_coco_annotations when two entries in the images array resolve to the same canonical path, detected via the annotations dict keyed by resolved image_path. COCO requires each image to appear exactly once; duplicates would silently overwrite each other's Detections.","triggerScenarios":"Two images[] entries with identical file_name, or aliasing names like \"img.jpg\" and \"./img.jpg\" / \"sub/../img.jpg\" that resolve to the same path (resolution collapses aliases by design). Distinct ids with the same file_name also trigger it.","commonSituations":"Merging COCO files from multiple sources without deduplicating images; case-insensitive filesystems where 'A.jpg' and 'a.jpg' collide after resolution; JSON edited by hand to add an image that already exists.","solutions":["Deduplicate the images array on file_name (keep one entry and remap its annotations' image_id).","If two different images share a basename, move them into subdirectories and use distinct relative paths in file_name.","Use check on resolved paths: {Path(imgs_dir, e['file_name']).resolve() for e in data['images']} length must equal len(data['images'])."],"exampleFix":"// before\n\"images\": [{\"id\": 1, \"file_name\": \"a.jpg\", ...}, {\"id\": 2, \"file_name\": \"a.jpg\", ...}]\n\n// after\n\"images\": [{\"id\": 1, \"file_name\": \"a.jpg\", ...}]  # annotations for id 2 remapped to id 1 or second image renamed","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\ndef assert_unique_coco_images(annotations_path: str, images_dir: str) -> None:\n    \"\"\"Fail fast if two images[] entries resolve to the same path.\"\"\"\n    data = json.loads(Path(annotations_path).read_text())\n    seen: dict[Path, int] = {}\n    for img in data[\"images\"]:\n        p = Path(images_dir, img[\"file_name\"]).resolve()\n        if p in seen:\n            raise ValueError(f\"Duplicate file_name {img['file_name']!r} (also id {seen[p]})\")\n        seen[p] = img[\"id\"]","typeGuard":"def coco_images_are_unique(entries: list[dict], images_dir: str) -> bool:\n    \"\"\"True when all resolved image paths are distinct.\"\"\"\n    paths = [str(Path(images_dir, e[\"file_name\"]).resolve()) for e in entries]\n    return len(set(paths)) == len(paths)","tryCatchPattern":"try:\n    sv.DetectionDataset.from_coco(images_directory_path=d, annotations_path=a)\nexcept ValueError as exc:\n    if \"duplicate entries\" in str(exc):\n        # deduplicate on resolved path, remap annotations' image_id, then retry\n        ...\n    raise","preventionTips":["Deduplicate merged COCO files on resolved file_name before loading.","Put same-basename images in different subfolders and encode that in file_name.","Treat duplicate images[] entries as a bug in whatever merged the files."],"tags":["coco","dataset-load","duplicates","data-quality"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}