{"record":{"id":"91080c78a5d345b0","repo":"affaan-m/ECC","slug":"no-tier-tier-for-slot-slot-have-sorted-table-if-table-else-91080c","errorCode":null,"errorMessage":"no tier '{tier}' for slot '{slot}'; have {sorted(table) if table else 'no tiers'}","messagePattern":"no tier '(.+?)' for slot '(.+?)'; have (.+?)","errorType":"exception","errorClass":"FalError","httpStatus":null,"severity":"error","filePath":"skills/taste-distillation/scripts/taste/falapi.py","lineNumber":117,"sourceCode":"    },\n    \"text_to_3d\": {\n        \"best\": \"fal-ai/hunyuan-3d/v3.1/pro/text-to-3d\",\n        \"fast\": \"fal-ai/hunyuan-3d/v3.1/rapid/text-to-3d\",\n        \"value\": \"tripo3d/h3.1/text-to-3d\",\n    },\n    \"text_to_image\": {\n        \"best\": \"fal-ai/nano-banana-pro\",       # $0.15 flat, strongest identity\n        \"value\": \"fal-ai/flux-2-pro\",           # $0.03 first MP\n        \"instruct\": \"openai/gpt-image-2\",       # best typography / instructions\n    },\n}\n\n\ndef use_tier(slot: str, tier: str) -> str:\n    \"\"\"Repoint one slot at a named tier. Returns the endpoint now in use.\"\"\"\n    table = TIERS.get(slot)\n    if not table or tier not in table:\n        raise FalError(\n            f\"no tier '{tier}' for slot '{slot}'; \"\n            f\"have {sorted(table) if table else 'no tiers'}\"\n        )\n    ENDPOINTS[slot] = table[tier]\n    return ENDPOINTS[slot]\n\n\n# fal has NO endpoint that renders a mesh to images or video. The catalogue\n# splits 3D into image-to-3d, text-to-3d and 3d-to-3d, and every member of\n# 3d-to-3d emits another mesh - there is no 3d-to-image or 3d-to-video\n# category at all. So a minted GLB cannot re-enter the video graph on fal.\n#\n# It can re-enter locally: render a turntable here (taste/render3d.py), then\n# either assemble the frames with local ffmpeg or push them through\n# ``images_to_video`` above. That is why the 3D branch is not a dead end even\n# though the platform has no renderer.\nNO_RENDER_ENDPOINT = True\n","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-distillation/scripts/taste/falapi.py#L99-L135","documentation":"use_tier() repoints a model slot (e.g. 'image', 'video') at a named tier by looking up TIERS[slot][tier]. It raises falapi.FalError when the slot has no tier table or the tier name is absent from it, listing the valid tiers in the message. ENDPOINTS is only mutated on success.","triggerScenarios":"use_tier(slot, tier) called with a slot key not present in TIERS, or a tier string that doesn't match any key in that slot's table — e.g. use_tier('video', 'pro') when the video slot defines only {'fast': ..., 'quality': ...}.","commonSituations":"Tier name typo or wrong casing; tier renamed in a newer version of the library while scripts/config still use the old name; slot name typo ('vedio'); docs example using a tier this install doesn't define.","solutions":["Use one of the valid tiers listed in the message (sorted table contents) — e.g. use_tier('image', 'fast').","Print TIERS (or inspect falapi.py) to see available slots and tier names before switching.","Fix typos/casing in the tier or slot string; names are matched exactly.","If a tier was renamed after an upgrade, update call sites/config to the new tier name.","Wrap in try/except falapi.FalError to fall back to a default tier instead of failing."],"exampleFix":"// before\nfalapi.use_tier(\"video\", \"pro\")  # FalError: no tier 'pro'\n\n// after\ntry:\n    falapi.use_tier(\"video\", \"quality\")\nexcept falapi.FalError as exc:\n    print(exc)  # shows valid tiers; keep default endpoint","handlingStrategy":"validation","validationCode":"from taste import falapi\nslot_tiers = falapi.TIERS.get(\"video\", {})\nif tier not in slot_tiers:\n    raise SystemExit(f\"tier '{tier}' not in {sorted(slot_tiers)}\")","typeGuard":"def tier_exists(slot: str, tier: str) -> bool:\n    return tier in falapi.TIERS.get(slot, {})","tryCatchPattern":"try:\n    falapi.use_tier(slot, tier)\nexcept falapi.FalError as exc:\n    log.warning(\"tier switch failed, keeping default: %s\", exc)","preventionTips":["Inspect TIERS to list valid slots/tiers before switching","Copy tier names exactly (case-sensitive) from the message or source","Check for renames after upgrading the library","Wrap tier switches in try/except FalError with a sane default","Centralize tier names as constants instead of inline strings"],"tags":["configuration","enum","api","invalid-value"],"backgroundTag":"invalid-enum-value","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"}