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

  1. 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.
  2. 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.
  3. Upgrade (or pin) litellm to a single consistent version so the handler's provider lookup and ProviderConfigManager registry match: pip install -U litellm.
  4. 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

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


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/b943e2376387eac7. Report an issue: GitHub.