BerriAI/litellm · error · SystemExit
Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassi
Error message
Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassified)}. Add them to the key tables in {Path(__file__).name} and rerun it. What it means
litellm routes image_variation calls through ProviderConfigManager.get_provider_image_variation_config (litellm/utils.py:8603), which only registers configs for the openai and topaz providers. When the lookup returns None, the OpenAI image variations handler raises this ValueError before any HTTP call is made. Note the handler catches it in its broad except (handler.py:220) and re-raises it wrapped in an OpenAIError with status 500, so the message surfaces inside an OpenAIError. In this version the lookup is hard-coded to LlmProviders.OPENAI (handler.py:133), so hitting it means the litellm.OpenAIImageVariationConfig symbol was replaced/missing, or you are on an older litellm where the lookup used custom_llm_provider directly.
Source
Thrown at ci_cd/generate_model_prices_schema.py:225
def classify(key: str, modes: tuple) -> Optional[JsonSchema]:
curated = {**OBJECT_KEYS, **ARRAY_KEYS, **string_key_schemas(modes), **INTEGER_KEYS, **NUMBER_KEYS}
if key in curated:
return curated[key]
if key.startswith("supports_") or key in EXTRA_BOOLEAN_KEYS:
return BOOLEAN
if "cost" in key:
return cost_schema(key)
return None
def build_schema(prices: dict) -> JsonSchema:
entries = {name: entry for name, entry in prices.items() if name not in SPECIAL_ROOT_KEYS}
all_keys = tuple(sorted({key for entry in entries.values() for key in entry}))
modes = tuple(sorted({entry["mode"] for entry in entries.values() if "mode" in entry}))
unclassified = tuple(key for key in all_keys if classify(key, modes) is None)
if unclassified:
raise SystemExit(
f"Unclassified keys in {PRICES_PATH.name}: {', '.join(unclassified)}. "
f"Add them to the key tables in {Path(__file__).name} and rerun it."
)
entry_properties = {key: classify(key, modes) for key in all_keys}
return {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "LiteLLM model_prices_and_context_window.json",
"description": (
"Schema for LiteLLM's model price and context window registry "
"(https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json). "
"Every top-level key except 'sample_spec' and 'fallback_generalizations' is a model id, "
"optionally prefixed with its provider (e.g. 'azure/gpt-5.4'), mapping to a model entry. "
"All costs are USD per unit. New optional fields are added regularly, so consumers should "
"ignore unknown fields rather than reject them."
),
"type": "object",
"properties": {
"sample_spec": {View on GitHub (pinned to 6c2dcb801b)
Solutions
- Call the endpoint with a provider that ships an image-variation config: use model="dall-e-2" (or "topaz/...") so the config lookup resolves to OpenAIImageVariationConfig or TopazImageVariationConfig instead of returning None.
- If you intended OpenAI, remove any custom_llm_provider override / model prefix (e.g. drop "azure/" or "openai/" routing that funnels into an unsupported path) and let the call route to the default OpenAI handler.
- Upgrade (or pin) litellm to a single consistent version so the handler's provider lookup and ProviderConfigManager registry match: pip install -U litellm.
- If you replaced litellm.OpenAIImageVariationConfig (monkeypatch/test stub), restore the original class or ensure your replacement subclasses BaseImageVariationConfig and is assigned on the litellm module.
Example fix
# before
resp = litellm.image_variation(
model="azure/dall-e-2", # azure has no image-variation config registered
image=open("cat.png", "rb"),
)
# after
resp = litellm.image_variation(
model="dall-e-2", # routes to OpenAIImageVariationConfig
image=open("cat.png", "rb"),
) Defensive patterns
Strategy: validation
Validate before calling
from litellm.types.utils import LlmProviders
from litellm.utils import ProviderConfigManager
provider = "openai" # the provider you intend to route to
config = ProviderConfigManager.get_provider_image_variation_config(
model="dall-e-2",
provider=LlmProviders(provider),
)
if config is None:
raise RuntimeError(
f"{provider} has no image-variation config; use 'openai' (dall-e-2) or 'topaz'"
) Type guard
from litellm.llms.base_llm.image_variations.transformation import BaseImageVariationConfig
from litellm.utils import ProviderConfigManager
from litellm.types.utils import LlmProviders
def supports_image_variation(provider: str) -> bool:
"""True if litellm ships an image-variation config for this provider."""
try:
cfg = ProviderConfigManager.get_provider_image_variation_config(
model="", provider=LlmProviders(provider)
)
except ValueError:
return False
return isinstance(cfg, BaseImageVariationConfig) Try / catch
from litellm.llms.openai.common_utils import OpenAIError
try:
resp = litellm.image_variation(model="dall-e-2", image=img)
except (OpenAIError, ValueError) as e:
msg = str(e)
if "image variation provider not found" in msg:
# config-resolution failure: fix model/provider routing, do not retry
raise RuntimeError(f"unsupported image-variation provider: {msg}") from e
raise Prevention
- Route image_variation only to providers with a registered config: openai (dall-e-2) or topaz; check ProviderConfigManager.get_provider_image_variation_config before calling in CI.
- Never monkeypatch or delete litellm.OpenAIImageVariationConfig; if you must override it in tests, restore the original in a finally block.
- Pin litellm to an exact version in requirements so handler routing and the config registry cannot drift apart.
- Log custom_llm_provider alongside the model string when this error fires — the message interpolates the routed provider, which is the fastest way to spot a wrong model prefix like 'azure/dall-e-2'.
When it happens
Trigger: Calling litellm.image_variation()/async_image_variation with a model routed to a provider that has no image-variation config registered (e.g. model="azure/dall-e-2", "bedrock/...", "vertex_ai/..." on versions where the handler resolves the config from custom_llm_provider); monkeypatching or deleting litellm.OpenAIImageVariationConfig; running a litellm version where the handler/config registry shapes drifted apart after a partial upgrade.
Common situations: Pointing image_variation at a non-OpenAI deployment (Azure OpenAI, Bedrock, vLLM) that never supported the variations endpoint; upgrading litellm and hitting renamed/moved config classes; test suites that stub litellm internals without restoring them, leaving litellm.OpenAIImageVariationConfig unset.
Related errors
- No Braintrust API token provided. Pass via Authorization hea
- File not found. banned_keywords_list={banned_keywords_list}
- Unsupported provider config: {transcription_provider_config}
- Braintrust API error: {e.response.text}
- Failed to connect to Braintrust API: {str(e)}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/b943e2376387eac7.
Report an issue: GitHub.