calesthio/OpenMontage · error · FileNotFoundError

Image not found: {image_path}

Error message

Image not found: {image_path}

What it means

Raised by upload_image_fal as FileNotFoundError when the local image path passed in does not exist on disk. It is a pre-flight check before any network activity, so seeing it means no upload was attempted. Paths are used as-is; no search or workspace resolution is performed.

Source

Thrown at tools/video/_shared.py:428

            raise RuntimeError(f"HeyGen generation failed: {data.get('error', 'Unknown')}")

        time.sleep(min(interval, max(0.0, deadline - time.time())))
        interval = min(interval * 1.2, 30.0)

    raise TimeoutError(f"HeyGen execution {execution_id} timed out after {timeout}s")


def upload_image_fal(image_path: str) -> str:
    """Upload a local image to fal.ai storage and return a public URL."""
    import requests

    api_key = os.environ.get("FAL_KEY") or os.environ.get("FAL_AI_API_KEY")
    if not api_key:
        raise RuntimeError("FAL_KEY or FAL_AI_API_KEY required for image upload")

    path = Path(image_path)
    if not path.exists():
        raise FileNotFoundError(f"Image not found: {image_path}")

    suffix = path.suffix.lower()
    content_type = {"png": "image/png", "jpg": "image/jpeg", "jpeg": "image/jpeg", "webp": "image/webp"}.get(
        suffix.lstrip("."), "image/png"
    )

    # Initiate upload
    init_resp = requests.post(
        "https://rest.alpha.fal.ai/storage/upload/initiate",
        headers={"Authorization": f"Key {api_key}", "Content-Type": "application/json"},
        json={"content_type": content_type, "file_name": path.name},
        timeout=30,
    )
    init_resp.raise_for_status()
    data = init_resp.json()

    # Upload file content
    put_resp = requests.put(

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Verify with Path(image_path).exists() before calling
  2. Pass absolute paths (Path(...).resolve()) to avoid cwd drift
  3. If you have a URL already, skip upload_image_fal — it is only for local files
  4. Regenerate the source image if a cleanup step removed it

Example fix

# before
upload_image_fal("assets/face.png")   # run from another cwd
# after
from pathlib import Path
upload_image_fal(str(Path("assets/face.png").resolve()))
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
p = Path(image_path).resolve()
if not p.is_file():
    raise FileNotFoundError(f"generate the image first: {image_path}")
upload_image_fal(str(p))

Type guard

def is_local_image(path: Any) -> bool:
    return isinstance(path, (str, Path)) and Path(path).is_file()

Prevention

When it happens

Trigger: Relative path resolved against a different cwd (subprocess, lambda, background worker); file deleted by a cleanup step between generation and upload; typo or wrong extension in the path; forward/backslash mismatch across platforms.

Common situations: Temp-file race where the generator wrote to /tmp but the uploader runs after tmp reaping; agent pipelines passing a URL instead of a local path to an upload-local-file helper.

Related errors


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