You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
blocking on_message_send treats a FAILED Task as a successful result #1228
Blocking DefaultRequestHandlerV2.on_message_send returns successfully when it sees a Task in any terminal state, including FAILED:
ifisinstance(event, Task) and (
params.configuration.return_immediatelyorevent.status.statein (TERMINAL_TASK_STATES|INTERRUPTED_TASK_STATES)
):
self._validate_task_id_match(task_id, event.id)
result=eventbreak
A producer crash that also emits TaskStatusUpdateEvent(FAILED) (with replace_status_update_with_task=True) therefore becomes a successful blocking message/send instead of an A2AClientError. Scenarios 9 and 12 encode the current contract: the producer exception must surface.
That is why #1191 persists FAILED + push on producer-failure but does not enqueue a FAILED status event on the subscriber stream. After #1191, a streaming client that survives the exception still cannot distinguish "the producer crashed" from "the connection dropped" without a get_task() poll.
Proposal
Treat a FAILED terminal Task as an error on the blocking path (or keep reading until the producer exception arrives), so a FAILED status event can be published to live streams without converting a crash into success. Until then, #1175's producer-failure half stays polling-dependent.
I reproduced this on current main: blocking on_message_send stops as soon as the FAILED Task replacement arrives, so the queued producer exception is never observed and the call returns successfully. I will keep that FAILED Task as the fallback result but continue consuming until the request completes or raises; clean agent-declared failures will still return their Task, while producer crashes will surface the original exception. I will add focused coverage for both paths and work on this now.
Activity
dawNotPoi commentedon Sep 4, 2026
I reproduced this on current main: blocking on_message_send stops as soon as the FAILED Task replacement arrives, so the queued producer exception is never observed and the call returns successfully. I will keep that FAILED Task as the fallback result but continue consuming until the request completes or raises; clean agent-declared failures will still return their Task, while producer crashes will surface the original exception. I will add focused coverage for both paths and work on this now.
fix(server): surface producer errors after failed tasks (#1229)