{"record":{"id":"54931e3932a2396b","repo":"roboflow/supervision","slug":"createml-annotation-refers-to-image-image-name","errorCode":null,"errorMessage":"CreateML annotation refers to image {image_name}, which resolves to the images directory itself ({images_directory_resolved}). Expected a path to an image file.","messagePattern":"CreateML annotation refers to image (.+?), which resolves to the images directory itself \\((.+?)\\)\\. Expected a path to an image file\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/formats/createml.py","lineNumber":37,"sourceCode":"def _resolve_image_path(images_directory_path: str, image_name: str) -> str:\n    \"\"\"Resolve and validate an image path against the images directory.\n\n    Rejects annotations whose ``image`` field escapes ``images_directory_path``\n    (via ``..`` traversal, an absolute path, or a symlink pointing outside),\n    mirroring the protection used by the COCO loader. Returns the canonical\n    resolved path so aliases collapse to a single dataset entry.\n    \"\"\"\n    images_directory_resolved = Path(images_directory_path).resolve()\n    image_path = Path(images_directory_path) / Path(image_name)\n    try:\n        resolved_image_path = image_path.resolve()\n    except (OSError, ValueError) as exc:\n        raise ValueError(\n            f\"CreateML 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\"CreateML 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 image file.\"\n        )\n    if images_directory_resolved not in resolved_image_path.parents:\n        raise ValueError(\n            f\"CreateML 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\"CreateML annotation refers to image {image_name!r}, which \"\n            f\"resolves to directory {resolved_image_path}. Expected a path \"\n            \"to an image file.\"\n        )\n    return str(resolved_image_path)\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/formats/createml.py#L19-L55","documentation":"Raised by _resolve_image_path in the CreateML loader when the entry's image field resolves to the images directory itself. The CreateML loader mirrors the COCO loader's path protection: image must name a real file inside images_directory_path, not the directory.","triggerScenarios":"A CreateML JSON entry with \"image\": \"\", \".\", or \"./\" — values that resolve to the images directory root. Hit when calling sv.dataset.formats.createml.load_createml_annotations (or DetectionDataset.from_createml).","commonSituations":"CreateML JSON produced by a script with an empty filename variable; hand-written annotation files; porting COCO-style data where the file_name field was left blank.","solutions":["Fix the empty/'.' image values in the CreateML JSON to real filenames.","Validate entries before loading: assert entry.get('image') not in (None, '', '.').","Regenerate the annotation file with a correct converter."],"exampleFix":"// before\n{\"image\": \"\", \"annotations\": [...]}\n\n// after\n{\"image\": \"photo1.jpg\", \"annotations\": [...]}","handlingStrategy":"validation","validationCode":"import json\nfrom pathlib import Path\n\ndef validate_createml_images(annotations_path: str, images_dir: str) -> None:\n    \"\"\"Fail fast on image fields that resolve to the images directory.\"\"\"\n    entries = json.loads(Path(annotations_path).read_text())\n    root = Path(images_dir).resolve()\n    for e in entries:\n        name = e.get(\"image\", \"\")\n        if not name or Path(root, name).resolve() == root:\n            raise ValueError(f\"Bad 'image' value {name!r} in entry {e!r}\")","typeGuard":"def is_valid_createml_image_field(name: object) -> bool:\n    \"\"\"True when image is a non-empty string naming a file, not the dir root.\"\"\"\n    return isinstance(name, str) and name.strip() not in (\"\", \".\", \"./\") and not name.endswith(\"/\")","tryCatchPattern":"try:\n    sv.DetectionDataset.from_createml(images_directory_path=d, annotations_path=a)\nexcept ValueError as exc:\n    if \"images directory itself\" in str(exc):\n        raise ValueError(f\"Fix empty 'image' fields in {a}\") from exc\n    raise","preventionTips":["Every CreateML entry must carry a real relative filename in 'image'.","Guard your converter: assert entry['image'] before writing JSON.","Reuse a pre-flight validator on any hand-edited annotation file."],"tags":["createml","dataset-load","path-validation","data-quality"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}