BerriAI/litellm · error · ValueError
api_base is required
Error message
api_base is required
What it means
ValueError raised by the Cohere v2 adapter's get_complete_url: unlike most providers, this handler does not append a path and does not synthesize a default — it requires api_base to already be set, and raises if it is None. LiteLLM normally injects the default https://api.cohere.com/v2 upstream of this call, so hitting this error means the defaulting layer was bypassed or explicitly overridden with None.
Solutions
- Pass api_base="https://api.cohere.com/v2" (or your proxy's equivalent full path) in the completion call
- If the var may be unset, fall back: api_base=os.environ.get('COHERE_API_BASE') or 'https://api.cohere.com/v2'
- In Router model_list entries, ensure the cohere_v2 model has api_base set or remove the key so litellm applies its default
- Upgrade litellm — default URL handling for cohere_v2 has changed across versions
Example fix
# before
litellm.completion(
model="cohere_v2/command-r-plus-08-2024",
messages=messages,
api_base=os.environ.get("COHERE_API_BASE"), # None when unset
)
# after
litellm.completion(
model="cohere_v2/command-r-plus-08-2024",
messages=messages,
api_base=os.environ.get("COHERE_API_BASE") or "https://api.cohere.com/v2",
) Defensive patterns
Strategy: validation
Validate before calling
import os
api_base = os.environ.get("COHERE_API_BASE") or "https://api.cohere.com/v2"
litellm.completion(
model="cohere_v2/command-r-plus-08-2024",
messages=messages,
api_base=api_base,
) Try / catch
try:
litellm.completion(model="cohere_v2/command-r", messages=messages, api_base=maybe_base)
except ValueError as e:
if "api_base is required" in str(e):
litellm.completion(
model="cohere_v2/command-r", messages=messages, api_base="https://api.cohere.com/v2"
)
else:
raise Prevention
- Never forward os.environ.get('COHERE_API_BASE') without an 'or' default
- In Router model_list, either set api_base for cohere_v2 deployments or omit the key entirely
- Centralize provider URL defaults in one config module so None never reaches the adapter
When it happens
Trigger: Calling a cohere_v2 model (or Cohere v2 path) with api_base=None passed explicitly through router/completion kwargs, or through an integration that forwards its own api_base value without a default.
Common situations: Litellm Router configs where api_base is conditionally set and forwards None; wrapper code doing completion(..., api_base=os.environ.get('COHERE_API_BASE')) when the var is unset; custom providers routing cohere_v2 through generic paths that skip default URL resolution.
Related errors
- api_base is required for Generic Guardrail API. Set…
- api_base is required
- api_base is required
- api_base is required for A2A provider
- api_base is required for A2A provider. Either provide…
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/74c1873d2cf0e673.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/llms/cohere/chat/v2_transformation.py:285
sync_stream=sync_stream,
json_mode=json_mode,
)
def get_complete_url(
self,
api_base: str | None,
api_key: str | None,
model: str,
optional_params: dict,
litellm_params: dict,
stream: bool | None = None,
) -> str:
"""
Get the complete URL for Cohere v2 chat completion.
The api_base should already include the full path.
"""
if api_base is None:
raise ValueError("api_base is required")
return api_base
def get_error_class(self, error_message: str, status_code: int, headers: dict | httpx.Headers) -> BaseLLMException:
return CohereError(status_code=status_code, message=error_message)
def _translate_citations_to_openai_annotations(self, citations: list[dict]) -> list[ChatCompletionAnnotation]:
"""
Transform Cohere citations to OpenAI annotations format.
Creates separate annotations for each source in a citation, allowing multiple
annotations with the same start/end index if they reference different sources.
Args:
citations: List of Cohere citation objects with format:
{
"start": int,
"end": int,
"text": str,View on GitHub (pinned to 77b7c6c40c)