BerriAI/litellm · error · ValueError

api_base is required for Pydantic AI agents

Error message

api_base is required for Pydantic AI agents

What it means

PydanticAIHandler.handle_non_streaming raises ValueError when api_base is None before sending the A2A message to the Pydantic AI agent over HTTP. The handler performs the raw HTTP POST itself, so it must be told where the agent listens.

Source

Thrown at litellm/a2a_protocol/providers/pydantic_ai_agents/handler.py:49

        timeout: float = 60.0,
        agent_extra_headers: dict[str, str] | None = None,
    ) -> dict[str, Any]:
        """
        Handle non-streaming request to Pydantic AI agent.

        Args:
            request_id: A2A JSON-RPC request ID
            params: A2A MessageSendParams containing the message
            api_base: Base URL of the Pydantic AI agent
            timeout: Request timeout in seconds
            agent_extra_headers: Per-request headers (from x-a2a-{agent}-* rewrite and
                admin extra_headers) to forward on the upstream HTTP call.

        Returns:
            A2A SendMessageResponse dict
        """
        if api_base is None:
            raise ValueError("api_base is required for Pydantic AI agents")
        verbose_logger.info("Pydantic AI: Routing to Pydantic AI agent at %s", api_base)

        # Send request directly to Pydantic AI agent
        response_data: Final = await PydanticAITransformation.send_non_streaming_request(
            api_base=api_base,
            request_id=request_id,
            params=params,
            timeout=timeout,
            agent_extra_headers=agent_extra_headers,
        )

        return response_data

    @staticmethod
    async def handle_streaming(
        request_id: str,
        params: dict[str, Any],
        api_base: str | None = None,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Pass the Pydantic AI agent URL as api_base
  2. Prefer going through PydanticAIProviderConfig / the standard bridge so api_base plumbing is handled

Example fix

# before
resp = await PydanticAIHandler.handle_non_streaming(request_id=rid, params=params, api_base=None)
# after
resp = await PydanticAIHandler.handle_non_streaming(request_id=rid, params=params, api_base="http://localhost:8000")
Defensive patterns

Strategy: validation

Validate before calling

if api_base is None:
    raise ValueError("PydanticAIHandler needs the agent URL")
resp = await PydanticAIHandler.handle_non_streaming(request_id=rid, params=params, api_base=api_base)

Prevention

When it happens

Trigger: Direct call to PydanticAIHandler.handle_non_streaming(request_id=..., params=..., api_base=None, ...).

Common situations: Bypassing the config layer and calling the handler directly; wiring code that drops api_base when translating from gateway config to handler kwargs.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/0453319c83cf613b. Report an issue: GitHub.