{"record":{"id":"d72dccfb8e032611","repo":"BerriAI/litellm","slug":"api-base-is-required-for-a2a-provider","errorCode":null,"errorMessage":"api_base is required for A2A provider","messagePattern":"api_base is required for A2A provider","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/a2a/chat/transformation.py","lineNumber":185,"sourceCode":"        Get the complete A2A agent endpoint URL.\n\n        A2A agents use JSON-RPC 2.0 at the base URL, not specific paths.\n        The method (message/send or message/stream) is specified in the\n        JSON-RPC request body, not in the URL.\n\n        Args:\n            api_base: Base URL of the A2A agent (e.g., \"http://0.0.0.0:9999\")\n            api_key: API key (not used for URL construction)\n            model: Model name (not used for A2A, agent determined by api_base)\n            optional_params: Optional parameters\n            litellm_params: LiteLLM parameters\n            stream: Whether this is a streaming request (affects JSON-RPC method)\n\n        Returns:\n            Complete URL for the A2A endpoint (base URL)\n        \"\"\"\n        if api_base is None:\n            raise ValueError(\"api_base is required for A2A provider\")\n\n        # A2A uses JSON-RPC 2.0 at the base URL\n        # Remove trailing slash for consistency\n        return api_base.rstrip(\"/\")\n\n    def transform_request(\n        self,\n        model: str,\n        messages: list[AllMessageValues],\n        optional_params: dict,\n        litellm_params: dict,\n        headers: dict,\n    ) -> dict:\n        \"\"\"\n        Transform OpenAI request to A2A JSON-RPC 2.0 format.\n\n        Args:\n            model: Model name","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/a2a/chat/transformation.py#L167-L203","documentation":"ValueError raised by the A2A provider's get_url when api_base is None. A2A agents are addressed entirely by their base URL (JSON-RPC 2.0 at that URL; the model name does not select a host), so without api_base the request cannot be routed anywhere and fails fast.","triggerScenarios":"litellm.completion(model='a2a/my_agent', ...) with no api_base in the call, deployment, or litellm_params; api_base set under a misspelled key (base_url) or only in an unrelated env var.","commonSituations":"First-time A2A usage assuming a default agent registry; proxy deployments whose model_list entry for the a2a model lacks litellm_params.api_base; config migrated from another provider where the base URL key differs.","solutions":["Pass api_base explicitly: litellm.completion(model='a2a/x', api_base='http://host:9999', ...).","In proxy config, add litellm_params: {model: a2a/x, api_base: http://host:9999} to the model_list entry.","Check for key typos (base_url vs api_base) and that the value is not None/empty.","Verify the agent is reachable at that URL and speaks A2A JSON-RPC 2.0 at the base path."],"exampleFix":"# before\nresp = litellm.completion(model=\"a2a/agent\", messages=[{\"role\": \"user\", \"content\": \"hi\"}])\n# ValueError: api_base is required for A2A provider\n\n# after\nresp = litellm.completion(\n    model=\"a2a/agent\",\n    api_base=\"http://localhost:9999\",\n    messages=[{\"role\": \"user\", \"content\": \"hi\"}],\n)","handlingStrategy":"validation","validationCode":"api_base = kwargs.get(\"api_base\") or os.getenv(\"A2A_API_BASE\")\nif not api_base:\n    raise ValueError(\"api_base is required for A2A provider (e.g. http://localhost:9999)\")\nresp = litellm.completion(model=\"a2a/agent\", api_base=api_base, messages=messages)","typeGuard":"def is_valid_a2a_target(api_base: object) -> bool:\n    if not isinstance(api_base, str) or not api_base.strip():\n        return False\n    return api_base.startswith((\"http://\", \"https://\"))","tryCatchPattern":"try:\n    resp = litellm.completion(model=\"a2a/agent\", messages=messages, api_base=api_base)\nexcept ValueError as e:\n    if \"api_base is required\" in str(e):\n        raise HTTPException(status_code=400, detail=\"A2A deployment is missing api_base\")\n    raise","preventionTips":["Lint proxy config at startup: every model_list entry whose model starts with a2a/ must define litellm_params.api_base.","Remember the A2A model name selects the agent, not the host — the URL is the routing key.","Health-check the api_base URL (it must answer JSON-RPC 2.0) during deployment validation."],"tags":["a2a","api-base","provider-config","valueerror"],"backgroundTag":"missing-api-base-url","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}