Repository navigation
fix: guard against None converter results in RemoteA2aAgent handlers - #5219
giulio-leone wants to merge 2 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Both _handle_a2a_response() and _handle_a2a_response_v2() dereference converter results (accessing event.content, event.custom_metadata) without guarding against None. Converters can legitimately return None for messages with no convertible parts, metadata-only events, or empty status updates. Add None guards after each converter call in both handlers: - Legacy handler: 3 guards (task-no-update, status-update-message, artifact-update paths) + 1 guard (A2AMessage path) - V2 handler: 1 guard (A2AMessage path; tuple path was already guarded) The fix returns None (skip event) which is consistent with the existing pattern in the v2 tuple branch and is properly handled by the caller in _run_async_impl via 'if not event: continue'. Fixes google#5187
285dbb3 to
22df0cc
Compare
|
Hi @giulio-leone , Thank you for your contribution! We appreciate you taking the time to submit this pull request. Your PR has been received by the team and is currently under review. We will provide feedback as soon as we have an update to share. |
|
Hi @wukath , can you please review this. |
Merge #5219 ## Summary Fixes #5187 — `AttributeError: 'NoneType' object has no attribute 'custom_metadata'` crash in `RemoteA2aAgent` when converter functions return `None`. ## Root Cause Both `_handle_a2a_response()` (legacy) and `_handle_a2a_response_v2()` (v2) dereference converter results (e.g. `event.custom_metadata`, `event.content`) without checking for `None`. The v2-default converters in `to_adk_event.py` legitimately return `None` via `_create_event()` when there are no convertible parts and no event actions — this is by design for metadata-only updates, empty status changes, etc. ## Fix Add `if not event: return None` guards after each converter call site: | Handler | Path | Guard added | |---------|------|------------| | Legacy (`_handle_a2a_response`) | Task converter — no status update | ✅ | | Legacy (`_handle_a2a_response`) | Message converter — status update with message | ✅ | | Legacy (`_handle_a2a_response`) | Task converter — artifact update | ✅ | | Legacy (`_handle_a2a_response`) | A2AMessage response | ✅ | | V2 (`_handle_a2a_response_v2`) | A2AMessage response | ✅ | | V2 (`_handle_a2a_response_v2`) | Tuple response | Already guarded (line 572) | Returning `None` is consistent with the existing pattern in the v2 tuple branch and is properly handled by the caller in `_run_async_impl` via `if not event: continue`. ## Testing - Reproduced both crashes before the fix - Verified both crashes are resolved after the fix - Added 8 regression tests in `TestRemoteA2aAgentNoneConverterResults` covering all converter paths in both handlers - All 103 tests pass (95 existing + 8 new), 0 failures Co-authored-by: George Weale <gweale@google.com> COPYBARA_INTEGRATE_REVIEW=#5219 from giulio-leone:fix/remote-a2a-none-converter-crash 21f4de7 PiperOrigin-RevId: 937711023
|
Thank you @giulio-leone for your contribution! 🎉 Your changes have been successfully imported and merged via Copybara in commit 2e3d717. Closing this PR as the changes are now in the main branch. |
Merge google#5219 ## Summary Fixes google#5187 — `AttributeError: 'NoneType' object has no attribute 'custom_metadata'` crash in `RemoteA2aAgent` when converter functions return `None`. ## Root Cause Both `_handle_a2a_response()` (legacy) and `_handle_a2a_response_v2()` (v2) dereference converter results (e.g. `event.custom_metadata`, `event.content`) without checking for `None`. The v2-default converters in `to_adk_event.py` legitimately return `None` via `_create_event()` when there are no convertible parts and no event actions — this is by design for metadata-only updates, empty status changes, etc. ## Fix Add `if not event: return None` guards after each converter call site: | Handler | Path | Guard added | |---------|------|------------| | Legacy (`_handle_a2a_response`) | Task converter — no status update | ✅ | | Legacy (`_handle_a2a_response`) | Message converter — status update with message | ✅ | | Legacy (`_handle_a2a_response`) | Task converter — artifact update | ✅ | | Legacy (`_handle_a2a_response`) | A2AMessage response | ✅ | | V2 (`_handle_a2a_response_v2`) | A2AMessage response | ✅ | | V2 (`_handle_a2a_response_v2`) | Tuple response | Already guarded (line 572) | Returning `None` is consistent with the existing pattern in the v2 tuple branch and is properly handled by the caller in `_run_async_impl` via `if not event: continue`. ## Testing - Reproduced both crashes before the fix - Verified both crashes are resolved after the fix - Added 8 regression tests in `TestRemoteA2aAgentNoneConverterResults` covering all converter paths in both handlers - All 103 tests pass (95 existing + 8 new), 0 failures Co-authored-by: George Weale <gweale@google.com> COPYBARA_INTEGRATE_REVIEW=google#5219 from giulio-leone:fix/remote-a2a-none-converter-crash 21f4de7 PiperOrigin-RevId: 937711023
Summary
Fixes #5187 —
AttributeError: 'NoneType' object has no attribute 'custom_metadata'crash inRemoteA2aAgentwhen converter functions returnNone.Root Cause
Both
_handle_a2a_response()(legacy) and_handle_a2a_response_v2()(v2) dereference converter results (e.g.event.custom_metadata,event.content) without checking forNone. The v2-default converters into_adk_event.pylegitimately returnNonevia_create_event()when there are no convertible parts and no event actions — this is by design for metadata-only updates, empty status changes, etc.Fix
Add
if not event: return Noneguards after each converter call site:_handle_a2a_response)_handle_a2a_response)_handle_a2a_response)_handle_a2a_response)_handle_a2a_response_v2)_handle_a2a_response_v2)Returning
Noneis consistent with the existing pattern in the v2 tuple branch and is properly handled by the caller in_run_async_implviaif not event: continue.Testing
TestRemoteA2aAgentNoneConverterResultscovering all converter paths in both handlers