{"record":{"id":"b160282fa14ce435","repo":"JuliusBrussee/caveman","slug":"label-currency-must-be-usd","errorCode":null,"errorMessage":"{label}: currency must be USD","messagePattern":"(.+?): currency must be USD","errorType":"validation","errorClass":"CatalogError","httpStatus":null,"severity":"error","filePath":"shared/provider-catalog/validate_catalog.py","lineNumber":131,"sourceCode":"    return parsed.astimezone(timezone.utc)\n\n\ndef validate_row(row: dict[str, Any], label: str, now: datetime) -> tuple[str, str, str]:\n    unknown = set(row) - TOP_LEVEL_KEYS\n    missing = REQUIRED_KEYS - set(row)\n    if unknown:\n        raise CatalogError(f\"{label}: unknown field(s): {', '.join(sorted(unknown))}\")\n    if missing:\n        raise CatalogError(f\"{label}: missing field(s): {', '.join(sorted(missing))}\")\n\n    identity: list[str] = []\n    for field in (\"provider\", \"model\", \"region\"):\n        value = row[field]\n        if not isinstance(value, str) or not IDENTIFIER.fullmatch(value):\n            raise CatalogError(f\"{label}: {field} must be a safe non-empty identifier\")\n        identity.append(value)\n    if row[\"currency\"] != \"USD\":\n        raise CatalogError(f\"{label}: currency must be USD\")\n\n    pricing = row[\"pricing\"]\n    if not isinstance(pricing, dict):\n        raise CatalogError(f\"{label}: pricing must be an object\")\n    pricing_unknown = set(pricing) - PRICING_KEYS\n    if pricing_unknown:\n        raise CatalogError(f\"{label}: unknown pricing field(s): {', '.join(sorted(pricing_unknown))}\")\n    for required in (\"input_per_million\", \"output_per_million\"):\n        if required not in pricing:\n            raise CatalogError(f\"{label}: pricing.{required} is required\")\n    for field, value in pricing.items():\n        if value is None or field == \"long_context_threshold_inclusive\":\n            if field == \"long_context_threshold_inclusive\" and value is not None and not isinstance(value, bool):\n                raise CatalogError(f\"{label}: pricing.{field} must be boolean or null\")\n            continue\n        if isinstance(value, bool) or not isinstance(value, (int, float)):\n            raise CatalogError(f\"{label}: pricing.{field} must be numeric or null\")\n        if not math.isfinite(value) or value < 0:","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/provider-catalog/validate_catalog.py#L113-L149","documentation":"A row's `currency` is not the literal string \"USD\". All prices in this catalog are denominated in USD — cross-currency rows would corrupt the no-fake-savings cost math — so the validator pins the currency exactly. Thrown from validate_row.","triggerScenarios":"A row has `currency: usd` (lowercase), `currency: EUR`, `currency: null`, or omits any currency normalization, e.g. after copying a price from a provider page quoting in another currency.","commonSituations":"Copying a European provider/VAT-inclusive EUR price; a lowercase typo; a sync script carrying through a currency field from a third-party models dataset; new row authored from a non-US pricing page.","solutions":["Set `currency: USD` exactly (uppercase)","If your source price is in another currency, convert it to USD and cite the USD figure from the provider's pricing page (usually switchable to USD)","Remove any stray currency field value like null or an empty string and write USD"],"exampleFix":"# before\ncurrency: usd\n\n# after\ncurrency: USD","handlingStrategy":"validation","validationCode":"def currency_ok(row: dict) -> bool:\n    return row.get(\"currency\") == \"USD\"","typeGuard":"def is_usd(value: object) -> bool:\n    return value == \"USD\"","tryCatchPattern":"try:\n    validate_catalog()\nexcept CatalogError as e:\n    if \"currency must be USD\" in str(e):\n        normalize_currency(str(e))","preventionTips":["Convert any non-USD source price to USD before adding a row","Always write the literal uppercase `USD`","Assert currency == USD in any script that emits rows"],"tags":["currency","validation","yaml","catalog"],"backgroundTag":"invalid-enum-value","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}