NousResearch/hermes-agent · error · ValueError

Image file not found: {image_arg}

Error message

Image file not found: {image_arg}

What it means

ValueError from the CLI image-attachment path in cli.py:3971: the explicitly passed --image argument could not be resolved to an existing file by _resolve_attachment_path, so the run is aborted before the message is sent. (A second, related check immediately after rejects files whose suffix is not in _IMAGE_EXTENSIONS.)

Source

Thrown at cli.py:3971

    return min(max(visual_lines, 1), max(1, int(max_height or 1)))


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.

View on GitHub (pinned to c896c09c42)

Solutions

  1. Check the file exists at exactly that path from the same cwd (or pass an absolute path).
  2. Quote the argument if it contains spaces: hermes --image "/path/with spaces/photo.png".
  3. Confirm the extension is a supported image type (_IMAGE_EXTENSIONS) once the path resolves — 'Not a supported image file' is the sibling error.
  4. For programmatic callers, resolve and validate with Path(...).is_file() before invoking the CLI.

Example fix

# before
$ hermes 'describe this' --image screenshots/latest.png   # cwd-dependent, typo
ValueError: Image file not found: screenshots/latest.png

# after
$ hermes 'describe this' --image "$HOME/Pictures/screenshots/latest.png"
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

_IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp"}

def image_arg_ok(arg: str) -> bool:
    p = Path(arg).expanduser()
    return p.is_file() and p.suffix.lower() in _IMAGE_EXTENSIONS

Try / catch

try:
    run_with_image(prompt, image_arg=path)
except ValueError as exc:
    if "not found" in str(exc) or "Not a supported" in str(exc):
        print(f"check the image path: {exc}")
    raise

Prevention

When it happens

Trigger: Invoking the CLI with an image path that does not exist: typo, relative path resolved against an unexpected cwd, file on an unmounted share, or a path containing shell-unescaped spaces/globs. _resolve_attachment_path returning None is the trigger; only the resolved-not-None case proceeds to the extension check.

Common situations: Dragging a path from a file manager that includes quotes; running hermes from a different directory than where the image lives; the image was moved/deleted between compose and send; whitespace-only or empty argument after shell splitting.

Related errors


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