roboflow/supervision · error · FileNotFoundError

Error: Couldn't load the icon image from {icon_path}

Error message

Error: Couldn't load the icon image from {icon_path}

What it means

Raised by the cached icon loader used by `IconAnnotator` when `cv2.imread` returns None for the given path — i.e. the file does not exist, is unreadable, or is not a decodable image. OpenCV silently returns None for unreadable files, so supervision converts that into an explicit FileNotFoundError with the offending path.

Source

Thrown at src/supervision/annotators/core.py:64

from supervision.utils.image import (
    _overlay_image,
    crop_image,
    letterbox_image,
    scale_image,
)
from supervision.utils.logger import _get_logger

logger = _get_logger(__name__)


@lru_cache
def _load_icon_from_path(
    icon_path: str, icon_resolution_wh: tuple[int, int]
) -> npt.NDArray[np.uint8]:
    """Load and resize an icon image through a cache shared by annotators."""
    icon = cv2.imread(icon_path, cv2.IMREAD_UNCHANGED)
    if icon is None:
        raise FileNotFoundError(f"Error: Couldn't load the icon image from {icon_path}")
    icon_array = cast(npt.NDArray[np.uint8], icon)
    result: npt.NDArray[np.uint8] = letterbox_image(
        image=icon_array, resolution_wh=icon_resolution_wh
    )
    return result


def _normalize_color_input(color: Color | ColorPalette | str) -> Color | ColorPalette:
    """Normalize accepted color inputs to internal color objects.

    Accepts `Color`, `ColorPalette`, or hex string input. Hex strings are parsed via
    `hex_to_rgba` and converted to `Color` (alpha channel is ignored because annotator
    drawing uses RGB/BGR colors).
    """
    if isinstance(color, str):
        r, g, b, _ = hex_to_rgba(color)
        return Color.from_rgb_tuple((r, g, b))
    return color

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Verify the path exists with `pathlib.Path(icon_path).resolve()` and expand `~` with `expanduser()` before passing it.
  2. Use absolute paths anchored to your project root (e.g. `Path(__file__).parent / 'icons/warning.png'`).
  3. If icons are downloaded at runtime, wait for the download to complete and validate the file is a decodable image before annotating.

Example fix

# before
annotator = sv.IconAnnotator(icon_path="~/assets/alert.png")  # '~' not expanded

# after
from pathlib import Path
icon = Path("~/assets/alert.png").expanduser().resolve()
assert icon.is_file(), f"missing icon: {icon}"
annotator = sv.IconAnnotator(icon_path=str(icon))
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
import cv2

icon = Path(icon_path).expanduser().resolve()
assert icon.is_file(), f"icon not found: {icon}"
assert cv2.imread(str(icon)) is not None, f"icon not decodable: {icon}"
annotator = sv.IconAnnotator(icon_path=str(icon))

Try / catch

try:
    annotator.annotate(scene, detections)
except FileNotFoundError as e:
    logger.error("icon asset missing, skipping annotation: %s", e)
    # fallback: annotate without icons, do not crash the pipeline

Prevention

When it happens

Trigger: Calling `IconAnnotator(icon_path="icons/warning.png").annotate(...)` when the file is absent; passing a path with a leading '~' (not expanded by cv2.imread); a non-image or corrupted file; a path that exists inside a container but was not mounted/copied into the image.

Common situations: Relative paths resolved against a different working directory (script run from another folder); deploying to Docker where asset icons were not copied into the image; Windows/POSIX path separators in shared code; downloading icons at runtime and racing against the download.

Related errors


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