Skip to content

fix: guard against None converter results in RemoteA2aAgent handlers - #5219

Closed
giulio-leone wants to merge 2 commits into
google:mainfrom
giulio-leone:fix/remote-a2a-none-converter-crash
Closed

giulio-leone wants to merge 2 commits into
google:mainfrom
giulio-leone:fix/remote-a2a-none-converter-crash

Conversation

@giulio-leone

Copy link
Copy Markdown
Contributor

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

@google-cla

google-cla Bot commented Apr 9, 2026

Copy link
Copy Markdown

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.

@adk-bot adk-bot added the core [Component] This issue is related to the core interface and implementation label Apr 9, 2026
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
@giulio-leone
giulio-leone force-pushed the fix/remote-a2a-none-converter-crash branch from 285dbb3 to 22df0cc Compare April 9, 2026 03:01
@rohityan rohityan self-assigned this Apr 9, 2026
@rohityan

Copy link
Copy Markdown
Collaborator

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.

@rohityan

Copy link
Copy Markdown
Collaborator

Hi @wukath , can you please review this.

@rohityan rohityan added the needs review [Status] The PR/issue is awaiting review from the maintainer label Apr 13, 2026
@GWeale GWeale assigned GWeale and unassigned rohityan Jun 18, 2026
copybara-service Bot pushed a commit that referenced this pull request Jun 25, 2026
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
@adk-bot

adk-bot commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

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.

@adk-bot adk-bot added the merged [Status] This PR is merged label Jun 25, 2026
@adk-bot adk-bot closed this Jun 25, 2026
FrigaZzz pushed a commit to FrigaZzz/adk-python that referenced this pull request Aug 11, 2026
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core [Component] This issue is related to the core interface and implementation merged [Status] This PR is merged needs review [Status] The PR/issue is awaiting review from the maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RemoteA2aAgent handlers crash on None converter results (AttributeError)

4 participants