{"record":{"id":"7bf2ee7532a0114c","repo":"roboflow/supervision","slug":"coco-annotation-refers-to-image-image-name-whic-7bf2ee","errorCode":null,"errorMessage":"COCO annotation refers to image {image_name}, which resolves to {resolved_image_path} — outside the images directory {images_directory_resolved}.","messagePattern":"COCO annotation refers to image (.+?), which resolves to (.+?) — outside the images directory (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/formats/coco.py","lineNumber":541,"sourceCode":"        )\n        image_annotations = coco_annotations_groups.get(coco_image[\"id\"], [])\n        image_path = str(Path(images_directory_path) / Path(image_name))\n        try:\n            resolved_image_path = Path(image_path).resolve()\n        except (OSError, ValueError) as exc:\n            raise ValueError(\n                f\"COCO annotation refers to image {image_name!r}, which \"\n                f\"produces an invalid path: {exc}\"\n            ) from exc\n        if resolved_image_path == images_directory_resolved:\n            raise ValueError(\n                f\"COCO annotation refers to image {image_name!r}, which \"\n                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(","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/formats/coco.py#L523-L559","documentation":"Raised by load_coco_annotations when the resolved image path is not under the resolved images directory (images_directory_resolved is not among resolved_image_path.parents). This blocks absolute file_name values and '..' traversal in COCO annotations, keeping loads confined to the directory you passed.","triggerScenarios":"A COCO entry with file_name=\"/data/images/img.jpg\" (absolute path — joining then resolving yields the absolute path outside the images dir) or file_name=\"../../elsewhere/img.jpg\". Also triggered when the images directory itself is a symlink and file_name escapes it after resolution.","commonSituations":"COCO files generated on another machine with absolute paths baked in; annotation files from tools that store full paths instead of relative names; passing the wrong images_directory_path that does not actually contain the images.","solutions":["Rewrite file_name values in the JSON to bare relative filenames (e.g. 'img.jpg' or 'subdir/img.jpg').","Verify images_directory_path actually points to the directory containing the images referenced by the file.","One-liner fixup: json load, set img['file_name'] = os.path.basename(img['file_name']) for each entry, dump back."],"exampleFix":"// before (JSON entry)\n{\"file_name\": \"/home/user/datasets/coco/train/images/000001.jpg\", ...}\n\n// after\n{\"file_name\": \"000001.jpg\", ...}","handlingStrategy":"validation","validationCode":"import json, os\nfrom pathlib import Path\n\ndef normalize_coco_file_names(annotations_path: str, images_dir: str) -> None:\n    \"\"\"Rewrite absolute/traversal file_name values to safe relative names.\"\"\"\n    data = json.loads(Path(annotations_path).read_text())\n    imgs_dir = Path(images_dir).resolve()\n    for img in data[\"images\"]:\n        if os.path.isabs(img[\"file_name\"]) or \"..\" in Path(img[\"file_name\"]).parts:\n            img[\"file_name\"] = os.path.basename(img[\"file_name\"])\n    Path(annotations_path).write_text(json.dumps(data))","typeGuard":"def is_confined_coco_file_name(name: str, images_dir: str) -> bool:\n    \"\"\"True when the joined resolved path stays strictly inside images_dir.\"\"\"\n    root = Path(images_dir).resolve()\n    return root in (root / name).resolve().parents","tryCatchPattern":"try:\n    sv.DetectionDataset.from_coco(images_directory_path=d, annotations_path=a)\nexcept ValueError as exc:\n    if \"outside the images directory\" in str(exc):\n        normalize_coco_file_names(a, d)  # strip absolute/traversal names, then retry\n    else:\n        raise","preventionTips":["Store only bare relative filenames or forward-slash subpaths in file_name.","Basename-ify file_name at generation time: file_name=os.path.basename(path).","Keep dataset trees self-contained so no annotation ever needs '..' or absolute paths."],"tags":["coco","dataset-load","path-traversal","security"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}