{"record":{"id":"dead863678a5be2a","repo":"roboflow/supervision","slug":"duplicate-image-basename-image-name-resolved-fro","errorCode":null,"errorMessage":"Duplicate image basename {image_name} resolved from multiple annotation files. All annotation files must reference unique image basenames.","messagePattern":"Duplicate image basename (.+?) resolved from multiple annotation files\\. All annotation files must reference unique image basenames\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/formats/labelme.py","lineNumber":261,"sourceCode":"    for entry in entries:\n        shapes = entry.get(\"shapes\", [])\n        raw_image_path = entry.get(\"imagePath\")\n        if not raw_image_path:\n            raise ValueError(\n                \"A LabelMe annotation file is missing the required \"\n                \"'imagePath' field or it is empty.\"\n            )\n        # ponytail: basename-only, no symlink resolution — images_directory_path\n        # is trusted; annotation-driven traversal is neutralised by .name.\n        # See createml._resolve_image_path for the full .resolve()+parents pattern.\n        image_name = Path(raw_image_path).name\n        if not image_name or image_name in (\"..\", \".\"):\n            raise ValueError(\n                f\"LabelMe annotation has an invalid 'imagePath' {raw_image_path!r}.\"\n            )\n        image_path = str(Path(images_directory_path) / image_name)\n        if image_path in annotations:\n            raise ValueError(\n                f\"Duplicate image basename {image_name!r} resolved from multiple \"\n                \"annotation files. All annotation files must reference unique \"\n                \"image basenames.\"\n            )\n        with_masks = force_masks or any(\n            shape.get(\"shape_type\") == \"polygon\" for shape in shapes\n        )\n        if with_masks and not (entry.get(\"imageWidth\") and entry.get(\"imageHeight\")):\n            raise ValueError(\n                f\"LabelMe annotation for {image_name!r} requires \"\n                \"'imageWidth' and 'imageHeight' to build masks, but they are \"\n                \"missing or zero.\"\n            )\n        resolution_wh = (\n            int(entry.get(\"imageWidth\", 0)),\n            int(entry.get(\"imageHeight\", 0)),\n        )\n        annotations[image_path] = labelme_shapes_to_detections(","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/formats/labelme.py#L243-L279","documentation":"Raised when two different LabelMe annotation files reference imagePath values whose basenames collapse to the same image path. Detections are stored in a dict keyed by resolved image path, so a duplicate would silently overwrite one file's annotations; supervision instead fails and asks that all annotation files reference unique image basenames.","triggerScenarios":"DetectionDataset.from_labelme where e.g. a/ann1.json has imagePath \"img1.jpg\" and b/ann2.json has imagePath \"../img1.jpg\" — both basename to img1.jpg and resolve to the same path under images_directory_path.","commonSituations":"Merging annotation folders from multiple annotators of the same images; copying a project and keeping both copies of JSON in the annotations dir; annotating the same image in two subfolders; imagePath values differing only in directory components (basename is what counts).","solutions":["Search the annotations directory for JSONs referencing the duplicate basename named in the error: grep -l '\"img1.jpg\"' -r annotations_dir.","Delete or move the stale duplicate annotation (usually from an old copy or another annotator).","If two legitimate annotation sets exist for the same images, keep them in separate dataset directories and load separately.","Ensure your export pipeline never writes two annotation files whose imagePath basenames collide."],"exampleFix":"# before\nannotations/a.json -> \"imagePath\": \"img1.jpg\"\nannotations/b.json -> \"imagePath\": \"img1.jpg\"  # duplicate\n# after\nannotations/a.json -> \"imagePath\": \"img1.jpg\"\nannotations/old/b.json removed","handlingStrategy":"validation","validationCode":"from pathlib import Path\nfrom collections import Counter\n\ndef unique_image_basenames(json_entries: list[dict]) -> bool:\n    \"\"\"All LabelMe imagePath basenames must be unique across entries.\"\"\"\n    names = [Path(e['imagePath']).name for e in json_entries if e.get('imagePath')]\n    return max(Counter(names).values(), default=1) == 1","typeGuard":null,"tryCatchPattern":"try:\n    dataset = sv.DetectionDataset.from_labelme(images_dir, ann_dir)\nexcept ValueError as e:\n    if 'Duplicate image basename' in str(e):\n        raise SystemExit(f'Remove the stale duplicate annotation: {e}') from e\n    raise","preventionTips":["One annotations directory per annotation pass; do not merge annotator folders blindly.","Clean old copies of JSON when copying/renaming dataset folders.","Remember only the imagePath basename matters — directory parts are stripped."],"tags":["labelme","dataset","duplicate","annotation-format"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}