BerriAI/litellm · error · ValueError
api_base is required for PydanticAIProviderConfig
Error message
api_base is required for PydanticAIProviderConfig
What it means
PydanticAIProviderConfig.handle_non_streaming() forwards a request to a self-hosted Pydantic AI agent over HTTP and needs the agent's base URL to do so. If api_base arrives as None (it is optional in the signature), the config layer refuses to build the upstream call and raises this ValueError. In the LiteLLM A2A (agent-to-agent) routing layer, api_base comes from the deployment's litellm_params, so this almost always means the model entry for the pydantic_ai agent never configured one.
Solutions
- Add api_base to the deployment's litellm_params, e.g. litellm_params: {model: pydantic_ai/my-agent, api_base: http://localhost:8000}
- If calling programmatically, pass api_base="http://host:port" to the completion call for the pydantic_ai model
- Verify the param name is exactly api_base (not base_url / url) and that it sits inside litellm_params in config.yaml
- Confirm the Pydantic AI agent server is actually deployed at that URL and reachable from the proxy
Example fix
# before
response = litellm.completion(
model="pydantic_ai/my-agent",
messages=[{"role": "user", "content": "hello"}],
)
# after
response = litellm.completion(
model="pydantic_ai/my-agent",
messages=[{"role": "user", "content": "hello"}],
api_base="http://localhost:8000",
) Defensive patterns
Strategy: validation
Validate before calling
from litellm import Router
def assert_pydantic_ai_deployment_ready(deployment: dict) -> None:
lp = deployment.get("litellm_params", {})
if deployment["litellm_params"].get("model", "").startswith("pydantic_ai"):
if not lp.get("api_base"):
raise ValueError(
f"Deployment {deployment.get('model_name')} is missing api_base"
)
Type guard
def has_api_base(params: dict) -> bool:
"""True when params carry a usable api_base for pydantic_ai routing."""
return isinstance(params.get("api_base"), str) and len(params["api_base"].strip()) > 0
Try / catch
try:
result = await provider_config.handle_non_streaming(request_id, params, api_base=api_base)
except ValueError as e:
if "api_base is required" in str(e):
raise HTTPException(500, "Agent deployment missing api_base") from e
raise
Prevention
- Lint config.yaml at deploy time: every pydantic_ai deployment must set api_base
- Use env-var indirection with a startup check that fails fast when unset
- Keep one canonical config template for pydantic_ai agents that includes api_base
When it happens
Trigger: Calling litellm.completion()/acompletion() (or the A2A proxy route) with a model whose provider is pydantic_ai while the deployment/config has no api_base in litellm_params; invoking PydanticAIProviderConfig.handle_non_streaming(request_id, params) directly without api_base; passing api_base=None explicitly.
Common situations: Adding a Pydantic AI agent to a LiteLLM proxy model_list and forgetting the api_base line; copying an OpenAI-style config (api_key only) for a pydantic_ai deployment; renaming the param to base_url or url so it is silently ignored; the agent deployment YAML indentation putting api_base outside litellm_params.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- api_base is required for Pydantic AI agents
- api_base is required for Pydantic AI agents
- api_base is required
- api_base is required
- api_base is required for A2A provider
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/25232ca07514169e.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/a2a_protocol/providers/pydantic_ai_agents/config.py:29
class PydanticAIProviderConfig(BaseA2AProviderConfig):
"""
Provider configuration for Pydantic AI agents.
Pydantic AI agents follow A2A protocol but don't support streaming natively.
This config provides fake streaming by converting non-streaming responses into streaming chunks.
"""
async def handle_non_streaming(
self,
request_id: str,
params: dict[str, Any],
api_base: str | None = None,
**kwargs: Any,
) -> dict[str, Any]:
"""Handle non-streaming request to Pydantic AI agent."""
if api_base is None:
raise ValueError("api_base is required for PydanticAIProviderConfig")
return await PydanticAIHandler.handle_non_streaming(
request_id=request_id,
params=params,
api_base=api_base,
timeout=kwargs.get("timeout", 60.0),
agent_extra_headers=kwargs.get("agent_extra_headers"),
)
async def handle_streaming(
self,
request_id: str,
params: dict[str, Any],
api_base: str | None = None,
**kwargs,
) -> AsyncIterator[dict[str, Any]]:
"""Handle streaming request with fake streaming."""
if not api_base:
raise ValueError("api_base is required for Pydantic AI agents")View on GitHub (pinned to 77b7c6c40c)