calesthio/OpenMontage · error · HTTPException

media not found

Error message

media not found

What it means

Raised while resolving a reference (image/audio) that is neither a data: URI, an http(s):// or asset:// URL, nor an existing local file path. The tool checks the prefix first, then Path(value).is_file(); when both fail, the reference is unusable and rejected before any upload/encoding.

Source

Thrown at backlot/server.py:253

                hub.unsubscribe(q)

        return StreamingResponse(stream(), media_type="text/event-stream", headers={
            "Cache-Control": "no-cache",
            "X-Accel-Buffering": "no",
        })

    # ---- Thumbnails (downscaled, cached on disk) ------------------------

    @app.get("/thumb/{project_id}/{file_path:path}")
    async def thumb(project_id: str, file_path: str, w: int = 640) -> FileResponse:
        project_dir = _safe_project_dir(project_id)
        target = (project_dir / file_path).resolve()
        try:
            target.relative_to(project_dir.resolve())
        except ValueError:
            raise HTTPException(status_code=403, detail="path escapes project")
        if not target.is_file():
            raise HTTPException(status_code=404, detail="media not found")
        width = min(THUMB_WIDTHS, key=lambda x: abs(x - w))
        cached = await asyncio.to_thread(_thumbnail_for, target, width)
        if cached is None:
            # Never fall back to raw video bytes for an <img> consumer (F-03);
            # non-thumbable images are safe to serve as-is.
            if target.suffix.lower() in {".mp4", ".webm", ".mov"}:
                raise HTTPException(status_code=404, detail="no poster frame available")
            return FileResponse(target)
        return FileResponse(cached, media_type="image/jpeg")

    # ---- Media (range requests handled by FileResponse) ---------------

    @app.get("/media/{project_id}/{file_path:path}")
    async def media(project_id: str, file_path: str) -> FileResponse:
        project_dir = _safe_project_dir(project_id)
        target = (project_dir / file_path).resolve()
        try:
            target.relative_to(project_dir.resolve())

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Verify the path exists from the process's working directory (use an absolute path via Path(...).resolve()).
  2. For remote storage (s3, ftp), download the file locally first or expose it behind a public https URL.
  3. For previously generated media in the pipeline, pass its asset:// ID instead of a filesystem path.

Example fix

# before
inputs = {"reference_image_path": "~/inputs/ref.png"}
# after
from pathlib import Path
inputs = {"reference_image_path": str(Path("~/inputs/ref.png").expanduser().resolve())}
Defensive patterns

Strategy: validation

Validate before calling

def resolve_ref(value):
    from pathlib import Path
    s = str(value)
    if s.startswith(("http://", "https://", "asset://", "data:")):
        return s
    p = Path(s).expanduser().resolve()
    if not p.is_file():
        raise FileNotFoundError(p)
    return str(p)

Type guard

def is_usable_ref(v) -> bool:
    from pathlib import Path
    s = str(v)
    return s.startswith(("http://", "https://", "asset://", "data:")) or Path(s).expanduser().is_file()

Try / catch

try:
    tool.run(inputs)
except ValueError as e:
    if "must be a public URL" in str(e):
        log_missing_ref(inputs)  # surface which reference path failed
        raise

Prevention

When it happens

Trigger: Passing reference_image_url="/home/me/missing.png" (typo or wrong working directory), a relative path that does not exist from the process cwd, an ftp:// or file:// URL, or a bare filename with no such file on disk.

Common situations: Agent runs in a container/sandbox where the path from a previous step was never copied in; relative paths resolved against a different cwd; ssh:// or s3:// style URIs the tool cannot consume.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/7c4353a1ef7f98b1. Report an issue: GitHub.