fix: DeleteTaskPushNotificationConfigAsync throws on valid null result - #433
Conversation
DeleteTaskPushNotificationConfig is the only A2A method with a void result. The generic JSON-RPC send helper unconditionally deserialized the response result and threw A2AException when it was null, so the client rejected the spec-compliant null-result success response that A2AJsonRpcProcessor itself produces. Split the transport/error handling into SendJsonRpcRequestCoreAsync and route delete through a void-result overload that skips result deserialization. Fixes a2aproject#429. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request refactors the A2AClient to support JSON-RPC methods that do not return a result (such as DeleteTaskPushNotificationConfigAsync) by introducing a non-generic SendJsonRpcRequestAsync overload and extracting the core request logic into SendJsonRpcRequestCoreAsync. A unit test has also been added to verify that the client completes successfully when receiving a null result. The review feedback suggests optimizing the new SendJsonRpcRequestAsync method by removing the async and await keywords and returning the task directly to avoid unnecessary state machine overhead.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
Verified this independently against current main. The root cause is exactly as described: The fix shape looks right: splitting out One housekeeping note: all build and test checks are green, the only failing check is the PR title validator, so a conventional prefix like |
|
@darrelmiller gentle ping on this one. It's a small client-side fix for #429: all checks are green, and another user independently reproduced both the bug and the root cause in the thread. While I'm here — is review bandwidth on |
|
@SergeyMenshykh since you're back in the repo today — would you mind taking a look at this one? It's a small client-side fix for #429 (the only A2A method with a void result; the client rejects the spec-compliant null result its own server returns). All checks are green, and another user independently reproduced the bug and root cause in the thread. Happy to reshape the void-result path if you'd prefer a different approach. |
Summary
Fixes #429.
A2AClient.DeleteTaskPushNotificationConfigAsyncalways threwA2AException: "Failed to deserialize JSON-RPC result."against a spec-compliant server — including this SDK's ownA2AJsonRpcProcessor, which answers delete with a success response whoseresultis null. A nullresulton success is valid JSON-RPC 2.0, andDeleteTaskPushNotificationConfigis the only A2A method with a void result, so it was the only method affected.Root cause
The generic send helper unconditionally deserialized
resultand threw on null:Delete routed through it with
TResult = object, leaving no path that tolerates a null result.Change
SendJsonRpcRequestAsync<TResult>into aSendJsonRpcRequestCoreAsynchelper that returns the rawJsonRpcResponse. The generic overload keeps its exact behavior (deserialize-or-throw) for all non-void methods.SendJsonRpcRequestAsyncoverload that surfaces JSON-RPC errors but skips result deserialization, and routedDeleteTaskPushNotificationConfigAsyncthrough it.No server-side change: the processor's null-result response is already spec-compliant.
Tests
DeletePushNotificationConfigAsync_CompletesOnNullResultreproduces the wire shape the server actually produces (Result = null); it fails withA2AExceptionbefore this change and passes after. The pre-existing delete test mocked the result as{}, which is why the regression was invisible.🤖 Generated with Claude Code