{"record":{"id":"ffa48fba41eee1c2","repo":"BerriAI/litellm","slug":"provider-custom-llm-provider-not-found","errorCode":null,"errorMessage":"Provider {custom_llm_provider} not found","messagePattern":"Provider (.+?) not found","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/get_llm_provider_logic.py","lineNumber":539,"sourceCode":"    Returns:\n        Tuple[str, str, Optional[str], Optional[str]]:\n            model: str\n            custom_llm_provider: str\n            dynamic_api_key: Optional[str]\n            api_base: Optional[str]\n    \"\"\"\n\n    custom_llm_provider = model.split(\"/\", 1)[0]\n    model = model.split(\"/\", 1)[1]\n\n    # Check JSON providers FIRST (before hardcoded ones)\n    from litellm.llms.openai_like.dynamic_config import create_config_class\n    from litellm.llms.openai_like.json_loader import JSONProviderRegistry\n\n    if JSONProviderRegistry.exists(custom_llm_provider):\n        provider_config: Final = JSONProviderRegistry.get(custom_llm_provider)\n        if provider_config is None:\n            raise ValueError(f\"Provider {custom_llm_provider} not found\")\n        config_class: Final = create_config_class(provider_config)\n        api_base, dynamic_api_key = config_class()._get_openai_compatible_provider_info(api_base, api_key)\n        return model, custom_llm_provider, dynamic_api_key, api_base\n\n    if custom_llm_provider == \"perplexity\":\n        # perplexity is openai compatible, we just need to set this to custom_openai and have the api_base be https://api.perplexity.ai\n        (\n            api_base,\n            dynamic_api_key,\n        ) = litellm.PerplexityChatConfig()._get_openai_compatible_provider_info(api_base, api_key)\n    elif custom_llm_provider == \"aiohttp_openai\":\n        return model, \"aiohttp_openai\", api_key, api_base\n    elif custom_llm_provider == \"anyscale\":\n        # anyscale is openai compatible, we just need to set this to custom_openai and have the api_base be https://api.endpoints.anyscale.com/v1\n        api_base = api_base or get_secret_str(\"ANYSCALE_API_BASE\") or \"https://api.endpoints.anyscale.com/v1\"\n        dynamic_api_key = api_key or get_secret_str(\"ANYSCALE_API_KEY\")\n    elif custom_llm_provider == \"deepinfra\":\n        (","sourceCodeStart":521,"sourceCodeEnd":557,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/litellm_core_utils/get_llm_provider_logic.py#L521-L557","documentation":"Raised in _get_openai_compatible_provider_info() for models like '<slug>/model' where <slug> is a JSON-defined OpenAI-like provider loaded from litellm/llms/openai_like/providers.json via JSONProviderRegistry. exists(slug) returned True but get(slug) returned None — an inconsistent registry state. With the shipped registry this is close to impossible (values are never None), so hitting it means providers.json failed to load (the loader swallows errors with only a warning), was hand-edited/corrupted, or a custom registry subclass changed get().","triggerScenarios":"litellm.completion(model='<json-provider-slug>/some-model') after the providers.json file was modified, partially loaded due to a JSON parse error, or replaced by a fork; also possible in cut-down deployments that strip .json data files from the wheel.","commonSituations":"Editing providers.json to add a provider and breaking its structure; Docker images that exclude JSON data files; downgrades/upgrades that leave a stale registry; packaging tools (pyinstaller-style) omitting data files.","solutions":["Validate the registry at startup: JSONProviderRegistry.get(slug) must return a SimpleProviderConfig with base_url and api_key_env before you call that model.","Restore the stock providers.json (reinstall litellm: pip install --force-reinstall litellm) or fix your edited copy so every slug maps to a valid config.","Pin a known-good litellm version if this appeared after an upgrade.","If the file is intact, report the bug upstream with your litellm version and model string."],"exampleFix":"# before\nlitellm.completion(model='my-json-provider/llama-3')  # ValueError: Provider my-json-provider not found\n\n# after\nfrom litellm.llms.openai_like.json_loader import JSONProviderRegistry\ncfg = JSONProviderRegistry.get('my-json-provider')\nassert cfg is not None and cfg.base_url and cfg.api_key_env, 'fix providers.json entry'\nlitellm.completion(model='my-json-provider/llama-3')","handlingStrategy":"validation","validationCode":"from litellm.llms.openai_like.json_loader import JSONProviderRegistry\n\nslug = model.split('/', 1)[0]\ncfg = JSONProviderRegistry.get(slug)\nif cfg is None or not getattr(cfg, 'base_url', None):\n    raise RuntimeError(f'JSON provider {slug!r} is not properly registered; fix providers.json')\nresp = litellm.completion(model=model)","typeGuard":"from litellm.llms.openai_like.json_loader import SimpleProviderConfig\n\ndef is_registered_json_provider(slug: str) -> bool:\n    cfg = JSONProviderRegistry.get(slug)\n    return isinstance(cfg, SimpleProviderConfig) and bool(cfg.base_url)","tryCatchPattern":"try:\n    resp = litellm.completion(model='my-json-provider/llama-3')\nexcept ValueError as e:\n    if 'not found' in str(e):\n        # registry inconsistent: reinstall litellm or repair providers.json\n        raise\n    raise","preventionTips":["Run a startup smoke test over the JSON provider slugs your config references.","Keep providers.json under version control and JSON-validate it in CI.","Include package data files when packaging litellm into bundles."],"tags":["litellm","openai-like","provider-registry","json-config","packaging"],"backgroundTag":"missing-provider-config","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}