BerriAI/litellm · error · RuntimeError
A2A send_message failed: no response received after retry…
Error message
A2A send_message failed: no response received after retry attempts.
What it means
_execute_a2a_send_with_retry loops the non-streaming send (retrying once after a localhost-card rewrite). If the loop ends without ever capturing a successful response — retries exhausted or every attempt failing in a way that produced no response object — this RuntimeError is raised. It is the aggregate 'attempted but never succeeded' error for message/send.
Solutions
- Verify the agent is up and the URL is right: curl <api_base>/.well-known/agent-card.json
- Check logs for a preceding 'Retrying with base URL' warning — if present, fix the agent's advertised card URL
- Wrap asend_message with your own retry/backoff for transient outages
- Inspect the original underlying exception in the traceback (the retry wrapper re-raises it) to classify network vs agent error
Defensive patterns
Strategy: retry
Validate before calling
import httpx
async def agent_ready(api_base: str) -> bool:
try:
async with httpx.AsyncClient(timeout=5) as hc:
return hc and (await hc.get(f'{api_base.rstrip("/")}/.well-known/agent-card.json')).is_success
except httpx.HTTPError:
return False
if not await agent_ready(api_base):
raise RuntimeError(f'A2A agent not reachable at {api_base}') Try / catch
last = None
for attempt in range(3):
try:
resp = await asend_message(a2a_client=client, request=req, api_base=api_base)
break
except RuntimeError as e:
if 'after retry attempts' not in str(e):
raise
last = e
await asyncio.sleep(2 ** attempt)
else:
raise RuntimeError(f'A2A agent unreachable after backoff: {api_base}') from last Prevention
- Validate api_base with a card fetch at startup and on config reload
- Circuit-break agents that repeatedly fail instead of hard-failing user requests
- Watch for the localhost-retry warning in logs; it usually precedes this error
When it happens
Trigger: api_base unreachable (agent down, wrong host/port) so every attempt errors; a localhost-card retry succeeded logistically but the resent request still failed; retry budget consumed by transient network errors.
Common situations: Pointing at a stopped agent container; wrong port in api_base; flaky network between litellm and the agent; agent restarting mid-request.
Related errors
- A2A send_message_streaming failed: no response received…
- Cannot retry A2A localhost URL fix: no agent card is…
- Cannot retry A2A localhost URL fix: the client was not…
- A2A SDK is required for localhost retry handling. Install…
- A2A send_message failed: no response received from agent.
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/3393829dfb8150e7.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/a2a_protocol/main.py:311
is_streaming=False,
)
card_url = get_agent_card_url(agent_card) if agent_card else None
except Exception as e:
try:
map_a2a_exception(e, card_url, api_base, model=agent_name)
except A2ALocalhostURLError as localhost_err:
a2a_client = await handle_a2a_localhost_retry(
error=localhost_err,
agent_card=agent_card,
a2a_client=a2a_client,
is_streaming=False,
)
card_url = get_agent_card_url(agent_card) if agent_card else None
continue
except Exception:
raise
if a2a_response is None:
raise RuntimeError("A2A send_message failed: no response received after retry attempts.")
return a2a_response
async def _stream_messages(
a2a_client: "A2AClientType", request: "SendStreamingMessageRequest"
) -> AsyncIterator["SendStreamingMessageResponse"]:
"""Stream message events via a2a-sdk 1.x and yield JSON-RPC chunks."""
if _a2a_conversions is None:
raise ImportError(
"The 'a2a' package is required for A2A agent invocation. Install it with: pip install a2a-sdk"
)
pb_request: Final[CoreSendMessageRequest] = _a2a_conversions.to_core_send_message_request(request)
async for event in a2a_client.send_message(pb_request, context=_get_a2a_call_context(a2a_client)):
compat_chunk = _to_compat_stream_response(event, request_id=request.id)
yield SendStreamingMessageResponse(root=compat_chunk)
View on GitHub (pinned to 77b7c6c40c)