affaan-m/ECC · error · MissingKeyError

FAL_KEY is not set. Get a key at…

Error message

FAL_KEY is not set.
  Get a key at https://fal.ai/dashboard/keys, then either:
    export FAL_KEY='...'
  or run the pipeline offline with no key and no spend:
    export {DRY_RUN_ENV}=1      (or pass --dry-run)

What it means

falapi.api_key() reads the FAL_KEY environment variable after confirming the caller opted into live mode (require_live()). If the variable is unset or empty/whitespace, it raises MissingKeyError with instructions for obtaining a key at fal.ai/dashboard/keys. This guards against making paid fal.ai calls without credentials and points users at the offline --dry-run mode as a no-cost alternative.

Solutions

  1. Export the key in the current shell: export FAL_KEY='your-key-here' (obtain it at https://fal.ai/dashboard/keys).
  2. Persist the key in your environment (.env file loaded by the pipeline, shell profile, or CI secret store) so it survives new sessions.
  3. If you do not want to spend, run offline instead: export DRY_RUN_ENV=1 or pass --dry-run, which skips live calls entirely.
  4. Check for typos in the variable name and confirm it is exported (not just a local shell variable) and visible in the same environment the script runs in.

Example fix

# before
python -m taste.pipeline run   # MissingKeyError: FAL_KEY is not set.

# after
export FAL_KEY='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:secret'
python -m taste.pipeline run
Defensive patterns

Strategy: try-catch

Validate before calling

import os
if not os.environ.get("FAL_KEY", "").strip():
    raise SystemExit("FAL_KEY is not set; export it or use --dry-run")

Type guard

def has_fal_key(env: dict[str, str]) -> bool:
    return bool(env.get("FAL_KEY", "").strip())

Try / catch

try:
    result = generate(...)
except MissingKeyError:
    logger.warning("no FAL_KEY; falling back to dry-run mode")
    result = generate(dry_run=True)

Prevention

When it happens

Trigger: Calling any live API path — api_key() is invoked by submit() and upload() — when os.environ['FAL_KEY'] is missing, empty, or contains only whitespace after strip(), and live mode has already been opted into via require_live().

Common situations: Fresh clone without a .env file; CI environment where the secret was never injected; running inside a container/sandbox that does not inherit shell exports; exporting FAL_KEY in one shell but running the script in another; typo like FAL_KEYS or fal_key; using `set FAL_KEY=...` (cmd.exe) syntax in bash or vice versa.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/1133fba2d2a290ca. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/taste/falapi.py:199

    if os.environ.get("TASTE_FORGE_ALLOW_LIVE") != "1":
        raise FalError("live transport requires TASTE_FORGE_ALLOW_LIVE=1")


def safe_url(url: str) -> str:
    """Log only origin: paths, queries and userinfo can carry signed secrets."""
    try:
        parsed = urllib.parse.urlsplit(url)
        return f"{parsed.scheme}://{parsed.hostname or '[invalid-host]'}"
    except ValueError:
        return "[invalid-url]"


def api_key() -> str:
    """Return ``FAL_KEY`` after live opt-in. Never logs the value."""
    require_live()
    key = os.environ.get("FAL_KEY", "").strip()
    if not key:
        raise MissingKeyError(
            "FAL_KEY is not set.\n"
            "  Get a key at https://fal.ai/dashboard/keys, then either:\n"
            "    export FAL_KEY='...'\n"
            "  or run the pipeline offline with no key and no spend:\n"
            f"    export {DRY_RUN_ENV}=1      (or pass --dry-run)"
        )
    return key


def _fal():
    """Import ``fal_client`` lazily so dry runs work even if it is absent."""
    try:
        import fal_client  # noqa: PLC0415 - deliberate lazy import
    except ImportError as exc:  # pragma: no cover - environment dependent
        raise FalError(
            "the 'fal_client' package is required for live calls: pip install fal-client"
        ) from exc
    return fal_client

View on GitHub (pinned to 8321021c54)