{"record":{"id":"e4c5c1dad7cdabca","repo":"affaan-m/ECC","slug":"fal-key-is-not-set-get-a-key-at-https-fal-ai-dashboard-keys-e4c5c1","errorCode":null,"errorMessage":"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    export {DRY_RUN_ENV}=1      (or pass --dry-run)","messagePattern":"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    export (.+?)=1      \\(or pass --dry-run\\)","errorType":"exception","errorClass":"MissingKeyError","httpStatus":null,"severity":"error","filePath":"skills/taste-distillation/scripts/taste/falapi.py","lineNumber":199,"sourceCode":"    if os.environ.get(\"TASTE_FORGE_ALLOW_LIVE\") != \"1\":\n        raise FalError(\"live transport requires TASTE_FORGE_ALLOW_LIVE=1\")\n\n\ndef safe_url(url: str) -> str:\n    \"\"\"Log only origin: paths, queries and userinfo can carry signed secrets.\"\"\"\n    try:\n        parsed = urllib.parse.urlsplit(url)\n        return f\"{parsed.scheme}://{parsed.hostname or '[invalid-host]'}\"\n    except ValueError:\n        return \"[invalid-url]\"\n\n\ndef api_key() -> str:\n    \"\"\"Return ``FAL_KEY`` after live opt-in. Never logs the value.\"\"\"\n    require_live()\n    key = os.environ.get(\"FAL_KEY\", \"\").strip()\n    if not key:\n        raise MissingKeyError(\n            \"FAL_KEY is not set.\\n\"\n            \"  Get a key at https://fal.ai/dashboard/keys, then either:\\n\"\n            \"    export FAL_KEY='...'\\n\"\n            \"  or run the pipeline offline with no key and no spend:\\n\"\n            f\"    export {DRY_RUN_ENV}=1      (or pass --dry-run)\"\n        )\n    return key\n\n\ndef _fal():\n    \"\"\"Import ``fal_client`` lazily so dry runs work even if it is absent.\"\"\"\n    try:\n        import fal_client  # noqa: PLC0415 - deliberate lazy import\n    except ImportError as exc:  # pragma: no cover - environment dependent\n        raise FalError(\n            \"the 'fal_client' package is required for live calls: pip install fal-client\"\n        ) from exc\n    return fal_client","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-distillation/scripts/taste/falapi.py#L181-L217","documentation":"MissingKeyError raised by api_key() in falapi.py when FAL_KEY is absent from the environment after live mode has been opted in. The library refuses to make any live fal.ai API call (submit or upload) without a credential, and deliberately never logs the key value. It also advertises the offline --dry-run path as a no-spend alternative.","triggerScenarios":"Calling submit() or upload() (directly or via text_to_image, image_to_3d, vlm_describe, etc.) in live mode while os.environ has no FAL_KEY (or only whitespace).","commonSituations":"Fresh clone where .env was not sourced; CI job without the secret configured; running in a new shell after exporting the key only in another terminal; typo'd variable name (FAL_API_KEY).","solutions":["Get a key at https://fal.ai/dashboard/keys and run: export FAL_KEY='...'","Load the key from .env in the shell or process environment before running the pipeline","Run offline with no spend: export the DRY_RUN_ENV variable to 1 or pass --dry-run","In CI, add FAL_KEY as a repository/environment secret and expose it to the job"],"exampleFix":"// before\n$ python pipeline.py            # MissingKeyError: FAL_KEY is not set.\n// after\n$ export FAL_KEY='<key from https://fal.ai/dashboard/keys>'\n$ python pipeline.py   # or: export FAL_DRY_RUN=1 to run offline","handlingStrategy":"validation","validationCode":"import os\nif not os.environ.get(\"FAL_KEY\", \"\").strip():\n    raise SystemExit(\"FAL_KEY not set; export it or run with --dry-run\")","typeGuard":null,"tryCatchPattern":"try:\n    url = falapi.submit(endpoint, payload)\nexcept falapi.MissingKeyError:\n    print(\"Set FAL_KEY or use --dry-run for offline mode\")","preventionTips":["Set FAL_KEY in your shell profile or .env and source it before runs","Check `os.environ.get(\"FAL_KEY\")` at script startup, fail fast","In CI, configure FAL_KEY as a secret injected into the environment","Use --dry-run / DRY_RUN_ENV=1 when you don't need live calls"],"tags":["python","missing-credentials","environment"],"backgroundTag":"missing-api-key","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}