{"record":{"id":"42293f7a64256e0c","repo":"BerriAI/litellm","slug":"base-url-is-required","errorCode":null,"errorMessage":"base_url is required","messagePattern":"base_url is required","errorType":"exception","errorClass":"AgentCardDiscoveryError","httpStatus":null,"severity":"error","filePath":"litellm/proxy/a2a/discovery.py","lineNumber":100,"sourceCode":"async def fetch_well_known_card(\n    base_url: str,\n    *,\n    discovery_mode: DiscoveryMode = DiscoveryMode.WELL_KNOWN_FALLBACK,\n    params: dict[str, Any] | None = None,\n    timeout: float = DEFAULT_DISCOVERY_TIMEOUT_SECONDS,\n    headers: dict[str, str] | None = None,\n) -> dict[str, Any]:\n    \"\"\"\n    Fetch an agent card from ``base_url`` using the strategy chosen by\n    ``discovery_mode``. Returns the parsed JSON from the first path that\n    responds with a JSON body.\n\n    Raises:\n        AgentCardDiscoveryError: if every path fails (network error, non-2xx,\n            or non-JSON body), or if the chosen mode is missing required params.\n    \"\"\"\n    if not base_url:\n        raise AgentCardDiscoveryError(\"base_url is required\")\n\n    normalized: Final = _normalize_base_url(base_url)\n    paths: Final = _paths_for_mode(discovery_mode, params)\n    client: Final = get_async_httpx_client(\n        llm_provider=httpxSpecialProvider.A2A,\n        params={\"timeout\": timeout},\n    )\n\n    last_error: str | None = None\n    for path in paths:\n        url = f\"{normalized}{path}\"\n        try:\n            # ``async_safe_get`` validates the URL against the SSRF blocklist\n            # (private/loopback IPs, cloud metadata endpoints, etc.) on every\n            # redirect hop. Even though the discovery endpoint is admin-only,\n            # we don't want a compromised admin key to be able to probe\n            # internal infrastructure through this fetcher.\n            # Pass ``headers or {}`` because ``async_safe_get`` (in the","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/a2a/discovery.py#L82-L118","documentation":"Guard inside fetch_well_known_card rejecting a call with a falsy base_url. The discovery function accepts keyword-only arguments and strategy flags, and this is the cheap pre-flight check before any HTTP attempt: with no base URL there is nothing to fetch .well-known agent cards from, so it fails fast with ValueError rather than a confusing URL-join error.","triggerScenarios":"Thrown at litellm/proxy/a2a/discovery.py:100 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Provide base_url for the agent discovery request."],"exampleFix":"base_url='https://agent.example.com'","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}