roboflow/supervision · error · ValueError

CreateML annotation refers to image {image_name}, which reso

Error message

CreateML annotation refers to image {image_name}, which resolves to {resolved_image_path} — outside the images directory {images_directory_resolved}.

What it means

Raised by _resolve_image_path in the CreateML loader when the resolved image path is not under the resolved images directory. It rejects absolute image paths and '..' traversal, confining loads to images_directory_path exactly like the COCO loader does.

Source

Thrown at src/supervision/dataset/formats/createml.py:43

    resolved path so aliases collapse to a single dataset entry.
    """
    images_directory_resolved = Path(images_directory_path).resolve()
    image_path = Path(images_directory_path) / Path(image_name)
    try:
        resolved_image_path = image_path.resolve()
    except (OSError, ValueError) as exc:
        raise ValueError(
            f"CreateML annotation refers to image {image_name!r}, which "
            f"produces an invalid path: {exc}"
        ) from exc
    if resolved_image_path == images_directory_resolved:
        raise ValueError(
            f"CreateML annotation refers to image {image_name!r}, which "
            f"resolves to the images directory itself "
            f"({images_directory_resolved}). Expected a path to an image file."
        )
    if images_directory_resolved not in resolved_image_path.parents:
        raise ValueError(
            f"CreateML annotation refers to image {image_name!r}, which "
            f"resolves to {resolved_image_path} — outside the images "
            f"directory {images_directory_resolved}."
        )
    if resolved_image_path.is_dir():
        raise ValueError(
            f"CreateML annotation refers to image {image_name!r}, which "
            f"resolves to directory {resolved_image_path}. Expected a path "
            "to an image file."
        )
    return str(resolved_image_path)


def createml_annotations_to_detections(
    image_annotations: list[CreateMLDict], class_to_index: dict[str, int]
) -> Detections:
    """Convert a single image's CreateML annotations into ``Detections``.

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Rewrite image fields to bare relative filenames: os.path.basename(entry['image']).
  2. Confirm images_directory_path is the directory that actually contains the referenced images.
  3. Post-process the JSON once: for e in data: e['image'] = os.path.basename(e['image']).

Example fix

// before
{"image": "/mnt/data/train/img_0001.jpg", ...}

// after
{"image": "img_0001.jpg", ...}
Defensive patterns

Strategy: validation

Validate before calling

import json, os
from pathlib import Path

def normalize_createml_images(annotations_path: str) -> None:
    """Rewrite absolute/traversal image values to bare filenames."""
    entries = json.loads(Path(annotations_path).read_text())
    for e in entries:
        if os.path.isabs(e["image"]) or ".." in Path(e["image"]).parts:
            e["image"] = os.path.basename(e["image"])
    Path(annotations_path).write_text(json.dumps(entries))

Type guard

def is_confined_createml_image(name: str, images_dir: str) -> bool:
    """True when the joined resolved path stays strictly inside images_dir."""
    root = Path(images_dir).resolve()
    return root in (root / name).resolve().parents

Try / catch

try:
    sv.DetectionDataset.from_createml(images_directory_path=d, annotations_path=a)
except ValueError as exc:
    if "outside the images directory" in str(exc):
        normalize_createml_images(a)  # then retry the load
    else:
        raise

Prevention

When it happens

Trigger: A CreateML entry with "image": "/abs/path/img.jpg" or "image": "../shared/img.jpg". Note: joining an absolute path with Path(images_dir) / Path(abs) yields the absolute path, which then fails the parents containment check.

Common situations: Annotation files generated on a different machine or by a tool that writes absolute paths; datasets reorganized after annotation creation; pointing images_directory_path at the wrong folder.

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/27a96eb120c17491. Report an issue: GitHub.