{"record":{"id":"0453319c83cf613b","repo":"BerriAI/litellm","slug":"api-base-is-required-for-pydantic-ai-agents-045331","errorCode":null,"errorMessage":"api_base is required for Pydantic AI agents","messagePattern":"api_base is required for Pydantic AI agents","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/a2a_protocol/providers/pydantic_ai_agents/handler.py","lineNumber":49,"sourceCode":"        timeout: float = 60.0,\n        agent_extra_headers: dict[str, str] | None = None,\n    ) -> dict[str, Any]:\n        \"\"\"\n        Handle non-streaming request to Pydantic AI agent.\n\n        Args:\n            request_id: A2A JSON-RPC request ID\n            params: A2A MessageSendParams containing the message\n            api_base: Base URL of the Pydantic AI agent\n            timeout: Request timeout in seconds\n            agent_extra_headers: Per-request headers (from x-a2a-{agent}-* rewrite and\n                admin extra_headers) to forward on the upstream HTTP call.\n\n        Returns:\n            A2A SendMessageResponse dict\n        \"\"\"\n        if api_base is None:\n            raise ValueError(\"api_base is required for Pydantic AI agents\")\n        verbose_logger.info(\"Pydantic AI: Routing to Pydantic AI agent at %s\", api_base)\n\n        # Send request directly to Pydantic AI agent\n        response_data: Final = await PydanticAITransformation.send_non_streaming_request(\n            api_base=api_base,\n            request_id=request_id,\n            params=params,\n            timeout=timeout,\n            agent_extra_headers=agent_extra_headers,\n        )\n\n        return response_data\n\n    @staticmethod\n    async def handle_streaming(\n        request_id: str,\n        params: dict[str, Any],\n        api_base: str | None = None,","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/a2a_protocol/providers/pydantic_ai_agents/handler.py#L31-L67","documentation":"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.","triggerScenarios":"Direct call to PydanticAIHandler.handle_non_streaming(request_id=..., params=..., api_base=None, ...).","commonSituations":"Bypassing the config layer and calling the handler directly; wiring code that drops api_base when translating from gateway config to handler kwargs.","solutions":["Pass the Pydantic AI agent URL as api_base","Prefer going through PydanticAIProviderConfig / the standard bridge so api_base plumbing is handled"],"exampleFix":"# before\nresp = await PydanticAIHandler.handle_non_streaming(request_id=rid, params=params, api_base=None)\n# after\nresp = await PydanticAIHandler.handle_non_streaming(request_id=rid, params=params, api_base=\"http://localhost:8000\")","handlingStrategy":"validation","validationCode":"if api_base is None:\n    raise ValueError(\"PydanticAIHandler needs the agent URL\")\nresp = await PydanticAIHandler.handle_non_streaming(request_id=rid, params=params, api_base=api_base)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call handlers through their config layer so plumbing is not manual","Keep agent URLs in one config object passed to every handler call"],"tags":["a2a","litellm","pydantic-ai","handler","missing-endpoint"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}