calesthio/OpenMontage · error · RuntimeError

HeyGen generation failed: {data.get('error', 'Unknown')}

Error message

HeyGen generation failed: {data.get('error', 'Unknown')}

What it means

Raised in the HeyGen execution poller when the execution status is 'failed' or 'error'. The message embeds data['error'] when present, otherwise 'Unknown'. This is HeyGen reporting the generation itself failed — bad inputs (script, avatar, voice ids), moderation rejection, quota/billing, or an internal HeyGen error.

Source

Thrown at tools/video/_shared.py:410

    interval = 5.0

    while time.time() < deadline:
        response = requests.get(url, headers=headers, timeout=30)
        response.raise_for_status()
        data = response.json().get("data", {})
        status = data.get("status", "")

        if status == "completed":
            video_url = (
                data.get("output", {}).get("video", {}).get("video_url")
                or data.get("output", {}).get("video_url")
            )
            if video_url:
                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}")

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Read the embedded error text — it names the actual cause
  2. For invalid ids: list current avatars/voices via the HeyGen API and update inputs
  3. For quota/billing: check the HeyGen dashboard before retrying
  4. For internal errors: retry once — these are often transient
Defensive patterns

Strategy: try-catch

Validate before calling

null

Try / catch

try:
    url = wait_for_video(execution_id)
except RuntimeError as e:
    err = str(e)
    if "quota" in err or "credit" in err:
        halt_and_alert_billing()
    elif "avatar" in err or "voice" in err or "not found" in err:
        inputs = refresh_avatar_voice_ids(inputs); resubmit()
    else:
        retry_once(inputs)  # internal errors are often transient
    raise

Prevention

When it happens

Trigger: Referencing a deleted avatar_id or voice_id; script with disallowed content; account out of credits; HeyGen internal error during render; malformed workflow payload accepted at submit but rejected at execution.

Common situations: Hard-coded avatar/voice ids that were removed from the workspace; expired HeyGen subscription; content moderation tripping on marketing copy with strong claims.

Related errors


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