BerriAI/litellm · error · ValueError
api_base is required for A2A provider
Error message
api_base is required for A2A provider
What it means
Raised by the A2A provider's URL builder in litellm when transforming a completion request: A2A agents are addressed purely by their api_base (JSON-RPC 2.0 at the base URL), so no api_base means no endpoint to call, and the transformation layer refuses with ValueError instead of constructing a broken URL. The trailing slash is stripped for consistency; model/api_key are not used for URL construction.
Source
Thrown at litellm/llms/a2a/chat/transformation.py:185
Get the complete A2A agent endpoint URL.
A2A agents use JSON-RPC 2.0 at the base URL, not specific paths.
The method (message/send or message/stream) is specified in the
JSON-RPC request body, not in the URL.
Args:
api_base: Base URL of the A2A agent (e.g., "http://0.0.0.0:9999")
api_key: API key (not used for URL construction)
model: Model name (not used for A2A, agent determined by api_base)
optional_params: Optional parameters
litellm_params: LiteLLM parameters
stream: Whether this is a streaming request (affects JSON-RPC method)
Returns:
Complete URL for the A2A endpoint (base URL)
"""
if api_base is None:
raise ValueError("api_base is required for A2A provider")
# A2A uses JSON-RPC 2.0 at the base URL
# Remove trailing slash for consistency
return api_base.rstrip("/")
def transform_request(
self,
model: str,
messages: list[AllMessageValues],
optional_params: dict,
litellm_params: dict,
headers: dict,
) -> dict:
"""
Transform OpenAI request to A2A JSON-RPC 2.0 format.
Args:
model: Model nameView on GitHub (pinned to 6c2dcb801b)
Solutions
- Set api_base to the A2A agent's URL (e.g. 'http://localhost:9999') in the litellm_params of your model config / completion call.
- If using environment templates (api_base: os.environ/A2A_BASE_URL), verify the variable is set in the proxy's environment.
- For the proxy, add the field to config.yaml: model_list: - model_name: my-agent, litellm_params: { model: a2a/my-agent, api_base: http://host:9999 }.
Example fix
# before
response = litellm.completion(
model="a2a/my-agent",
messages=[{"role": "user", "content": "hi"}],
) # ValueError: api_base is required for A2A provider
# after
response = litellm.completion(
model="a2a/my-agent",
api_base="http://127.0.0.1:9999",
messages=[{"role": "user", "content": "hi"}],
) Defensive patterns
Strategy: validation
Validate before calling
if model.startswith("a2a/") and not api_base:
raise ValueError("api_base is required for A2A models")
response = litellm.completion(model=model, api_base=api_base, messages=messages) Type guard
def is_a2a_ready(model: str, api_base) -> bool:
return not model.startswith("a2a/") or isinstance(api_base, str) and api_base.strip() != "" Try / catch
try:
response = litellm.completion(model="a2a/agent", api_base=api_base, messages=messages)
except ValueError as e:
if "api_base is required" in str(e):
raise HTTPException(400, "A2A model is missing api_base configuration")
raise Prevention
- Always set api_base (agent URL) in litellm_params for every a2a/ model_list entry.
- Validate required env vars for api_base at proxy startup, not per-request.
- Include an A2A config smoke test (one completion call) in deployment checks.
When it happens
Trigger: Calling litellm.completion(..., model='a2a/your-agent') (or a custom A2A deployment) without api_base — e.g. router/model_list entry for an A2A model missing the api_base field, or passing api_base=None explicitly.
Common situations: Configuring litellm Router/proxy with an a2a/ model but forgetting 'api_base' in the model_list entry; environment variable for A2A agent URL not set (litellm_params templating yields None); copy-pasting a config from an OpenAI-style model where api_base was optional; version changes that made api_base required for A2A.
Related errors
- Either a2a_client or api_base is required for standard A2A f
- 'username' is required in litellm_params when auth_mode='cp4
- api base needs to be a string. api_base={api_base}
- GEMINI_API_BASE is not set
- File not found. blocked_user_list={blocked_user_list}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/d72dccfb8e032611.
Report an issue: GitHub.