calesthio/OpenMontage · error · RuntimeError

FAL_KEY or FAL_AI_API_KEY required for image upload

Error message

FAL_KEY or FAL_AI_API_KEY required for image upload

What it means

Raised by upload_image_fal when neither FAL_KEY nor FAL_AI_API_KEY is set in the environment. Uploading a local image to fal.ai storage requires an authenticated key, so the function refuses before doing any I/O. The key is read only from these two environment variables.

Source

Thrown at tools/video/_shared.py:424

                return video_url
            raise RuntimeError(f"Completed but no video_url in output: {data}")

        if status in {"failed", "error"}:
            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()

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. export FAL_KEY=<key> (or FAL_AI_API_KEY) in the environment that runs the process
  2. For CI, add the key as a masked secret and map it to FAL_KEY
  3. If using a .env loader, verify it runs before tool invocation
  4. Prefer uploading to HeyGen directly via upload_image_heygen when you already have a HeyGen key

Example fix

# before
$ python make_video.py  # no key set
# after
$ export FAL_KEY="key-id:key-secret"
$ python make_video.py
Defensive patterns

Strategy: validation

Validate before calling

import os
if not (os.environ.get("FAL_KEY") or os.environ.get("FAL_AI_API_KEY")):
    raise RuntimeError("set FAL_KEY before running uploads")

Prevention

When it happens

Trigger: Running in a shell/process where the fal key was never exported; CI jobs with a sanitized env; .env file present but not loaded by the executing process; key named differently (e.g. FAL_API_KEY, which is NOT read).

Common situations: Local vs CI env drift; subprocess invocation that didn't inherit env; renaming conventions between FAL_KEY and FAL_AI_API_KEY across projects.

Related errors


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