NousResearch/hermes-agent · error · ValueError

Not a supported image file: {explicit_path}

Error message

Not a supported image file: {explicit_path}

What it means

Raised when an explicitly attached image argument resolves to an existing file whose extension is not in cli.py's _IMAGE_EXTENSIONS whitelist (defined at cli.py:3353, e.g. .png/.jpg/.jpeg/.gif/.webp). The path itself was already validated by _resolve_attachment_path, so only the file type is rejected. It exists to stop non-image files from being pushed into the vision pipeline.

Source

Thrown at cli.py:3973


def _collect_query_images(query: str | None, image_arg: str | None = None) -> tuple[str, list[Path]]:
    """Collect local image attachments for single-query CLI flows."""
    message = query or ""
    images: list[Path] = []

    if isinstance(message, str):
        dropped = _detect_file_drop(message)
        if dropped and dropped.get("is_image"):
            images.append(dropped["path"])
            message = dropped["remainder"] or f"[User attached image: {dropped['path'].name}]"

    if image_arg:
        explicit_path = _resolve_attachment_path(image_arg)
        if explicit_path is None:
            raise ValueError(f"Image file not found: {image_arg}")
        if explicit_path.suffix.lower() not in _IMAGE_EXTENSIONS:
            raise ValueError(f"Not a supported image file: {explicit_path}")
        images.append(explicit_path)

    deduped: list[Path] = []
    seen: set[str] = set()
    for img in images:
        key = str(img)
        if key in seen:
            continue
        seen.add(key)
        deduped.append(img)
    return message, deduped


# Strip OSC escape sequences (e.g. OSC-8 hyperlinks) that prompt_toolkit's
# ANSI parser can't handle — it strips \x1b but passes the payload through
# as literal text, garbling the TUI output.
_OSC_ESCAPE_RE = re.compile(r"\x1b\][\s\S]*?(?:\x07|\x1b\\)")

View on GitHub (pinned to c896c09c42)

Solutions

  1. Convert the file to a supported format (PNG or JPEG) before attaching, e.g. `magick input.bmp output.png`
  2. Check the whitelist in cli.py:3353 (_IMAGE_EXTENSIONS) to confirm your extension is genuinely unsupported
  3. If the format is a real image type the CLI should support, add the extension to _IMAGE_EXTENSIONS and re-run

Example fix

# before
hermes --image ~/Downloads/photo.heic "what is this?"
# ValueError: Not a supported image file: /home/u/Downloads/photo.heic

# after (convert first)
magick ~/Downloads/photo.heic ~/Downloads/photo.jpg
hermes --image ~/Downloads/photo.jpg "what is this?"
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
from cli import _IMAGE_EXTENSIONS

def is_supported_image(p: str) -> bool:
    return Path(p).suffix.lower() in _IMAGE_EXTENSIONS

Type guard

from pathlib import Path
from cli import _IMAGE_EXTENSIONS

def is_supported_image_path(p: Path) -> bool:
    return p.is_file() and p.suffix.lower() in _IMAGE_EXTENSIONS

Try / catch

try:
    msg, images = cli.prepare_message_with_images(text, image_arg=path)
except ValueError as e:
    if str(e).startswith("Not a supported image file"):
        show_error(f"{path}: convert to PNG/JPEG first")
    else:
        raise

Prevention

When it happens

Trigger: Calling the CLI with an explicit image attachment argument (image_arg) that points to a real file with an unsupported suffix, e.g. `--image photo.pdf`, `--image clip.bmp`, or `--image frame.tiff`. Any extension outside _IMAGE_EXTENSIONS throws; a missing file throws the different 'Image file not found' error one branch earlier.

Common situations: Attaching a PDF/HEIC screenshot from a phone, a .bmp from Windows paint, a file with an uppercase-but-unusual extension like .AVIF, or a typo'd extension (.jpq). Also renaming a file without converting it.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/6f9a9dd9196e10e1. Report an issue: GitHub.