{"record":{"id":"849f8bea093d77ef","repo":"BerriAI/litellm","slug":"either-a2a-client-or-api-base-is-required-for-stan","errorCode":null,"errorMessage":"Either a2a_client or api_base is required for standard A2A flow","messagePattern":"Either a2a_client or api_base is required for standard A2A flow","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/a2a_protocol/main.py","lineNumber":464,"sourceCode":"    if custom_llm_provider:\n        if request is None:\n            raise ValueError(\"request is required for completion bridge\")\n        return await _send_message_via_completion_bridge(\n            request=request,\n            custom_llm_provider=custom_llm_provider,\n            api_base=api_base,\n            litellm_params=litellm_params,\n            agent_extra_headers=agent_extra_headers,\n        )\n\n    # Standard A2A client flow\n    if request is None:\n        raise ValueError(\"request is required\")\n\n    # Create A2A client if not provided but api_base is available\n    if a2a_client is None:\n        if api_base is None:\n            raise ValueError(\"Either a2a_client or api_base is required for standard A2A flow\")\n        trace_id = trace_id or str(uuid.uuid4())\n        extra_headers: Final[dict[str, str]] = {\"X-LiteLLM-Trace-Id\": trace_id}\n        if agent_id:\n            extra_headers[\"X-LiteLLM-Agent-Id\"] = agent_id\n        # Overlay agent-level headers (agent headers take precedence over LiteLLM internal ones)\n        if agent_extra_headers:\n            extra_headers.update(agent_extra_headers)\n        a2a_client = await create_a2a_client(base_url=api_base, extra_headers=extra_headers)\n\n    # Type assertion: a2a_client is guaranteed to be non-None here\n    assert a2a_client is not None\n\n    agent_name: Final = _get_a2a_model_info(a2a_client, kwargs)\n\n    verbose_logger.info(\"A2A send_message request_id=%s, agent=%s\", request.id, agent_name)\n\n    # Get agent card URL for localhost retry logic\n    agent_card: Final = _get_a2a_client_agent_card(a2a_client)","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/a2a_protocol/main.py#L446-L482","documentation":"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.","triggerScenarios":"`await asend_message(request=req)` with both a2a_client=None and api_base=None (no custom_llm_provider routing).","commonSituations":"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.","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"],"exampleFix":"# before\nresp = await asend_message(request=req)\n# after\nresp = await asend_message(request=req, api_base=\"http://localhost:10001\")","handlingStrategy":"validation","validationCode":"if a2a_client is None and not api_base:\n    raise ValueError(\"configure api_base or pass a2a_client\")\nresp = await asend_message(request=request, a2a_client=a2a_client, api_base=api_base)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set api_base on every A2A deployment in proxy config","Create one a2a client per agent at startup and reuse it via a2a_client"],"tags":["a2a","litellm","config","missing-endpoint"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}