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
- Verify with Path(image_path).exists() before calling
- Pass absolute paths (Path(...).resolve()) to avoid cwd drift
- If you have a URL already, skip upload_image_fal — it is only for local files
- 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
- Always pass absolute resolved paths to upload helpers
- Verify the upstream generation succeeded before the upload step
- Don't pass URLs to a local-file uploader; download first or use URL inputs directly
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
- media not found
- Invalid stage: {stage!r} for pipeline {pipeline_type!r}. Val
- Pipeline manifest not found: {path}
- Playbook not found: {name}
- Error: No demo prop files were found in {PROPS_DIR}.
AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15).
Data as JSON: /api/errors/326f4405035cbf2f.
Report an issue: GitHub.