{"record":{"id":"74c1873d2cf0e673","repo":"BerriAI/litellm","slug":"api-base-is-required-74c187","errorCode":null,"errorMessage":"api_base is required","messagePattern":"api_base is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/cohere/chat/v2_transformation.py","lineNumber":285,"sourceCode":"            sync_stream=sync_stream,\n            json_mode=json_mode,\n        )\n\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        Get the complete URL for Cohere v2 chat completion.\n        The api_base should already include the full path.\n        \"\"\"\n        if api_base is None:\n            raise ValueError(\"api_base is required\")\n        return api_base\n\n    def get_error_class(self, error_message: str, status_code: int, headers: dict | httpx.Headers) -> BaseLLMException:\n        return CohereError(status_code=status_code, message=error_message)\n\n    def _translate_citations_to_openai_annotations(self, citations: list[dict]) -> list[ChatCompletionAnnotation]:\n        \"\"\"\n        Transform Cohere citations to OpenAI annotations format.\n\n        Creates separate annotations for each source in a citation, allowing multiple\n        annotations with the same start/end index if they reference different sources.\n\n        Args:\n            citations: List of Cohere citation objects with format:\n                {\n                    \"start\": int,\n                    \"end\": int,\n                    \"text\": str,","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/cohere/chat/v2_transformation.py#L267-L303","documentation":"Cohere v2's get_complete_url deliberately does not append any path — it expects api_base to already contain the full URL (including /v2/chat or /compat/v1/chat). If api_base is None at this point, it raises ValueError('api_base is required') rather than defaulting, because there is no safe default path to append. This differs from most providers where api_base is optional.","triggerScenarios":"Calling a cohere/ model through the v2 transformation with api_base unset — typically when the caller or a custom router/proxy config explicitly passes api_base=None, or a preceding URL-resolution step failed to seed the default COHERE_API_BASE. The v2 handler requires a resolved base, normally supplied from COHERE_API_BASE env or litellm defaults.","commonSituations":"Custom LLM routers or LiteLLM proxy configs that pass api_base: null entries; overriding cohere deployment config and accidentally nulling the base; library version regressions where the default api_base wiring changed.","solutions":["Set COHERE_API_BASE=https://api.cohere.com/compat/v1 (OpenAI-compat path) or pass api_base on the call containing the complete URL.","Audit proxy/router config: remove api_base: null / empty entries for cohere deployments so defaults apply.","Upgrade litellm if the default-URL seeding for v2 regressed in your version.","Verify with a plain litellm.completion call outside the proxy to isolate where api_base becomes None."],"exampleFix":"# before (router config nulls the base)\n# deployment: {model: cohere/command-r-plus, api_base: null}\n\n# after\n# deployment: {model: cohere/command-r-plus}\n# or explicitly:\nresponse = litellm.completion(\n    model=\"cohere/command-r-plus\", messages=[...],\n    api_base=\"https://api.cohere.com/compat/v1\",\n)","handlingStrategy":"validation","validationCode":"import os\n\nCOHERE_BASE = os.environ.get(\"COHERE_API_BASE\") or \"https://api.cohere.com/compat/v1\"\nassert COHERE_BASE.startswith(\"https://\"), \"cohere api_base must be a full URL\"","typeGuard":"from typing import Optional\n\ndef has_resolved_api_base(api_base: Optional[str]) -> bool:\n    \"\"\"True when api_base is usable for cohere v2 (full URL required).\"\"\"\n    return isinstance(api_base, str) and api_base.startswith((\"http://\", \"https://\"))","tryCatchPattern":"try:\n    resp = litellm.completion(model=\"cohere/command-r-plus\", messages=msgs)\nexcept ValueError as e:\n    if \"api_base is required\" in str(e):\n        resp = litellm.completion(\n            model=\"cohere/command-r-plus\", messages=msgs,\n            api_base=\"https://api.cohere.com/compat/v1\",\n        )\n    else:\n        raise","preventionTips":["Never write api_base: null for cohere entries in proxy/router configs — omit the key entirely.","Default COHERE_API_BASE explicitly in your environment so resolution never yields None.","Unit-test your router config against each provider with a minimal call."],"tags":["cohere","configuration","api-base"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}