{"record":{"id":"50505548bbe68f40","repo":"roboflow/supervision","slug":"cannot-export-dataset-image-paths-first-path-an","errorCode":null,"errorMessage":"Cannot export dataset: image paths {first_path} and {image_path} both map to {output_kind} file {first_name}. Ensure all image basenames are unique before exporting.","messagePattern":"Cannot export dataset: image paths (.+?) and (.+?) both map to (.+?) file (.+?)\\. Ensure all image basenames are unique before exporting\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/utils.py","lineNumber":185,"sourceCode":"        ```pycon\n        >>> from pathlib import Path\n        >>> from supervision.dataset.utils import check_no_basename_collisions\n        >>> check_no_basename_collisions(\n        ...     [\"a/img.jpg\", \"b/img.jpg\"], lambda p: Path(p).name, \"image\"\n        ... )\n        Traceback (most recent call last):\n        ...\n        ValueError: Cannot export dataset: image paths 'a/img.jpg' and ...\n\n        ```\n    \"\"\"\n    seen: dict[str, tuple[str, str]] = {}  # casefold(key) → (original name, image_path)\n    for image_path in image_paths:\n        output_name = key(image_path)\n        case_key = output_name.casefold()\n        if case_key in seen:\n            first_name, first_path = seen[case_key]\n            raise ValueError(\n                f\"Cannot export dataset: image paths {first_path!r} and \"\n                f\"{image_path!r} both map to {output_kind} file {first_name!r}. \"\n                \"Ensure all image basenames are unique before exporting.\"\n            )\n        seen[case_key] = (output_name, image_path)\n\n\ndef save_dataset_images(\n    dataset: DetectionDataset,\n    images_directory_path: str,\n    show_progress: bool = False,\n) -> None:\n    \"\"\"Save all images from a dataset to a directory.\n\n    Images already in memory are written with ``cv2.imwrite``; images stored\n    only as file paths are copied with ``shutil.copyfile``.\n\n    Args:","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/utils.py#L167-L203","documentation":"Raised by validate_image_paths (used by dataset exporters) when two different image paths produce the same output filename key in a case-insensitive sense (casefold is applied before duplicate detection). Exporters write one annotation/label file per image basename, so duplicate basenames — including 'A.jpg' vs 'a.jpg' on case-insensitive filesystems — would silently overwrite each other.","triggerScenarios":"Exporting a DetectionDataset containing both 'train/img.jpg' and 'val/img.jpg' (same basename, different directories) to YOLO/VOC/COCO via as_yolo/as_voc; also 'IMG.jpg' and 'img.jpg' colliding after casefold.","commonSituations":"Merging datasets that each have their own 'image_0001.jpg'; downloading datasets whose train/val folders reuse filenames; exporting on macOS/Windows where the filesystem itself is case-insensitive.","solutions":["Rename images before constructing the dataset so every basename is unique — e.g. prefix with the subfolder or dataset name.","Reconstruct the dataset with unique keys: rename files on disk or rewrite the image_paths/annotations dict keys.","Export each source dataset to a separate output directory instead of merging first."],"exampleFix":"// before\nds = DetectionDataset(classes=c, images=['a/img.jpg', 'b/img.jpg'], annotations=ann)\nds.as_yolo(...)  # ValueError: duplicate basenames\n\n// after\nimport shutil\nfor i, p in enumerate(ds.image_paths):\n    new_p = str(Path(out_dir) / f'{i:05d}_{Path(p).name}')\n    shutil.copy(p, new_p)\n    ds.annotations[new_p] = ds.annotations.pop(p)\n    ds.image_paths[ds.image_paths.index(p)] = new_p\nds.as_yolo(...)","handlingStrategy":"validation","validationCode":"keys = {Path(p).stem.casefold() for p in ds.image_paths}\nif len(keys) != len(ds.image_paths):\n    raise ValueError(\"Duplicate image basenames — rename before export\")\nds.as_yolo(...)","typeGuard":"def unique_basenames(paths: list[str]) -> bool:\n    stems = [Path(p).stem.casefold() for p in paths]\n    return len(stems) == len(set(stems))","tryCatchPattern":null,"preventionTips":["Rename images to globally unique basenames when merging datasets from different folders.","Remember the check is case-insensitive — 'A.jpg' and 'a.jpg' collide.","Run validate_image_paths yourself before long export jobs."],"tags":["dataset","export","filenames","validation"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}