BerriAI/litellm · error · ValueError
Either a2a_client or api_base is required for standard A2A f
Error message
Either a2a_client or api_base is required for standard A2A flow
What it means
Raised by asend_message in the standard A2A flow when neither an `a2a_client` nor an `api_base` was supplied. The function must either reuse an existing A2A client or build one from a base URL; with neither, there is no way to reach the agent.
Source
Thrown at litellm/a2a_protocol/main.py:464
if custom_llm_provider:
if request is None:
raise ValueError("request is required for completion bridge")
return await _send_message_via_completion_bridge(
request=request,
custom_llm_provider=custom_llm_provider,
api_base=api_base,
litellm_params=litellm_params,
agent_extra_headers=agent_extra_headers,
)
# Standard A2A client flow
if request is None:
raise ValueError("request is required")
# Create A2A client if not provided but api_base is available
if a2a_client is None:
if api_base is None:
raise ValueError("Either a2a_client or api_base is required for standard A2A flow")
trace_id = trace_id or str(uuid.uuid4())
extra_headers: Final[dict[str, str]] = {"X-LiteLLM-Trace-Id": trace_id}
if agent_id:
extra_headers["X-LiteLLM-Agent-Id"] = agent_id
# Overlay agent-level headers (agent headers take precedence over LiteLLM internal ones)
if agent_extra_headers:
extra_headers.update(agent_extra_headers)
a2a_client = await create_a2a_client(base_url=api_base, extra_headers=extra_headers)
# Type assertion: a2a_client is guaranteed to be non-None here
assert a2a_client is not None
agent_name: Final = _get_a2a_model_info(a2a_client, kwargs)
verbose_logger.info("A2A send_message request_id=%s, agent=%s", request.id, agent_name)
# Get agent card URL for localhost retry logic
agent_card: Final = _get_a2a_client_agent_card(a2a_client)View on GitHub (pinned to 6c2dcb801b)
Solutions
- Pass `api_base` (e.g. "http://localhost:10001") so a client is auto-created
- Or create a client once with `create_a2a_client(base_url=...)` and pass it as `a2a_client` for connection reuse
Example fix
# before resp = await asend_message(request=req) # after resp = await asend_message(request=req, api_base="http://localhost:10001")
Defensive patterns
Strategy: validation
Validate before calling
if a2a_client is None and not api_base:
raise ValueError("configure api_base or pass a2a_client")
resp = await asend_message(request=request, a2a_client=a2a_client, api_base=api_base) Prevention
- Set api_base on every A2A deployment in proxy config
- Create one a2a client per agent at startup and reuse it via a2a_client
When it happens
Trigger: `await asend_message(request=req)` with both a2a_client=None and api_base=None (no custom_llm_provider routing).
Common situations: Missing `api_base` in the model config when calling through LiteLLM proxy/gateway; refactoring code that previously created the client inline and dropping the base URL.
Related errors
- api_base is required for PydanticAIProviderConfig
- api_base is required for Pydantic AI agents
- api_base is required for Pydantic AI agents
- 'username' is required in litellm_params when auth_mode='cp4
- request is required
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/849f8bea093d77ef.
Report an issue: GitHub.