{"record":{"id":"25cea10af337ed31","repo":"BerriAI/litellm","slug":"api-base-is-required-25cea1","errorCode":null,"errorMessage":"api_base is required","messagePattern":"api_base is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/base_llm/chat/transformation.py","lineNumber":294,"sourceCode":"\n    def get_complete_url(\n        self,\n        api_base: str | None,\n        api_key: str | None,\n        model: str,\n        optional_params: dict,\n        litellm_params: dict,\n        stream: bool | None = None,\n    ) -> str:\n        \"\"\"\n        OPTIONAL\n\n        Get the complete url for the request\n\n        Some providers need `model` in `api_base`\n        \"\"\"\n        if api_base is None:\n            raise ValueError(\"api_base is required\")\n        return api_base\n\n    @abstractmethod\n    def transform_request(\n        self,\n        model: str,\n        messages: list[AllMessageValues],\n        optional_params: dict,\n        litellm_params: dict,\n        headers: dict,\n    ) -> dict:\n        pass\n\n    async def async_transform_request(\n        self,\n        model: str,\n        messages: list[AllMessageValues],\n        optional_params: dict,","sourceCodeStart":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/base_llm/chat/transformation.py#L276-L312","documentation":"This is the default get_complete_url in the base chat transformation config: if a provider config does not override URL building, the api_base string is used verbatim as the request URL, so None is rejected. Seeing it means your provider's request reached URL construction with no resolvable base URL.","triggerScenarios":"Using a provider/config combo whose get_complete_url is not overridden, with api_base=None and no provider-specific env var resolving it (OPENAI_API_BASE-style fallbacks belong to overridden configs). Common with custom/openai-compatible providers where you forgot base_url.","commonSituations":"Calling a custom/openai-compatible provider (model like 'openai/...' or a custom handler) without base_url/api_base; env var typos (OPENAI_BASE_URL vs OPENAI_API_BASE); proxy model entries missing api_base for openai-compatible endpoints.","solutions":["Pass the endpoint: litellm.completion(model='openai/my-model', ..., api_base='http://localhost:8000/v1') (or base_url)","Set the matching env var for the provider (e.g. OPENAI_API_BASE for openai/ prefixed models)","In proxy config.yaml, add api_base to the model's litellm_params","Verify the provider prefix in the model string matches the config you intended (model='openai/...' vs 'ollama/...')"],"exampleFix":"# before\nlitellm.completion(model='openai/my-finetune', messages=msgs, api_key=k)\n\n# after\nlitellm.completion(model='openai/my-finetune', messages=msgs, api_key=k, api_base='https://my-endpoint.example.com/v1')","handlingStrategy":"validation","validationCode":"api_base = os.environ.get('OPENAI_API_BASE') or kwargs.get('api_base')\nassert api_base, 'This provider requires api_base/base_url'","typeGuard":null,"tryCatchPattern":"try:\n    litellm.completion(model=model, messages=msgs)\nexcept ValueError as e:\n    if str(e) == 'api_base is required':\n        raise ConfigurationError(f'{model} needs an explicit endpoint') from e\n    raise","preventionTips":["Always set base_url for openai-compatible and custom providers","Keep provider env var names in one checked constants module"],"tags":["configuration","url","missing-parameter","base-provider"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}