Skip to content

fix: preserve JSON-native types in A2A metadata serialization - #5181

Closed
YizukiAme wants to merge 3 commits into
google:mainfrom
YizukiAme:clean/a2a-metadata-serialization
Closed

YizukiAme wants to merge 3 commits into
google:mainfrom
YizukiAme:clean/a2a-metadata-serialization

Conversation

@YizukiAme

@YizukiAme YizukiAme commented Apr 7, 2026 •

Copy link
Copy Markdown

Fixes #5183

Problem

_serialize_value() in from_adk_event.py falls through to str() for JSON-native Python types (dict, list, bool, int, float), corrupting structured metadata values into their string representations during A2A event conversion.

For example, a custom_metadata dict like {"retry": True, "max_attempts": 3} gets serialized as "{'retry': True, 'max_attempts': 3}" — a Python repr string instead of a proper JSON object.

Fix

  • Preserve JSON-native types directly: dict, list, str, bool, int, float are now returned as-is since they are already valid JSON values.
  • JSON normalization fallback: For other JSON-serializable objects (e.g., custom classes with __dict__), normalize via json.loads(json.dumps(value)) before falling back to str().
  • Added regression test for structured custom_metadata round-trip to ensure values are not corrupted to strings.

Logs After Fix

$ uv run pytest tests/unittests/a2a/converters/test_event_round_trip.py -v

tests/unittests/a2a/converters/test_event_round_trip.py::test_custom_metadata_structured_roundtrip PASSED

========== 143 passed, 124 warnings in 9.12s ==========

Testing Plan

uv run pytest tests/unittests/a2a/converters/ -v

All 143 A2A converter tests pass. The new test_custom_metadata_structured_roundtrip test verifies that dict, list, bool, int, and float values survive the _serialize_value() → metadata round-trip without being corrupted to strings.

@YizukiAme
YizukiAme marked this pull request as draft April 7, 2026 07:54
@YizukiAme
YizukiAme marked this pull request as ready for review April 7, 2026 08:04
@YizukiAme
YizukiAme force-pushed the clean/a2a-metadata-serialization branch from 7ef9c09 to 6f6c3b7 Compare April 9, 2026 01:30
@rohityan rohityan self-assigned this Apr 9, 2026
@YizukiAme
YizukiAme force-pushed the clean/a2a-metadata-serialization branch from 6f6c3b7 to f8be4ae Compare April 9, 2026 09:54
@rohityan rohityan added the a2a [Component] This issue is related a2a support inside ADK. label Apr 9, 2026
Comment thread src/google/adk/a2a/converters/from_adk_event.py Outdated
@rohityan rohityan added the request clarification [Status] The maintainer need clarification or more information from the author label Apr 9, 2026
@rohityan

rohityan commented Apr 9, 2026

Copy link
Copy Markdown
Collaborator

Hi @YizukiAme , Thank you for your contribution! We appreciate you taking the time to submit this pull request. Can you address my review comment.

@YizukiAme
YizukiAme force-pushed the clean/a2a-metadata-serialization branch 2 times, most recently from 732687d to 0aacc2b Compare April 9, 2026 19:30
@YizukiAme
YizukiAme requested a review from rohityan April 9, 2026 19:30
@YizukiAme
YizukiAme force-pushed the clean/a2a-metadata-serialization branch from 0aacc2b to d8e0e9d Compare April 10, 2026 11:06
@rohityan

rohityan commented Apr 13, 2026 •

Copy link
Copy Markdown
Collaborator

Hi @YizukiAme , Please fix formatting errors by running autoformat.sh

@YizukiAme

Copy link
Copy Markdown
Author

Hi @YizukiAme , Please fix formatting errors by running autoformat.sh

Hi, I’m currently away from my computer. I’ll fix the formatting issues in a few hours once I’m back! Thanks for pointing that out~

YizukiAme and others added 3 commits April 14, 2026 18:40
Signed-off-by: Yizuki_Ame <yinzimike@gmail.com>
Address review feedback: _serialize_value() now recurses into dict/list
values so that nested non-serializable types (datetime, set, etc.) are
gracefully handled instead of being passed through raw.

- str/bool/int/float: return as-is (JSON leaf types)
- dict: recurse into values, coerce keys to str
- list/tuple: recurse into elements
- set/frozenset: convert to sorted list, recurse
- Other: try json.loads(json.dumps(value, default=str)) fallback
- Added regression test for datetime and set inside custom_metadata
@YizukiAme
YizukiAme force-pushed the clean/a2a-metadata-serialization branch from 0c9ad08 to 07808fa Compare April 14, 2026 10:41
@YizukiAme

Copy link
Copy Markdown
Author

Done! Rebased on latest main and ran autoformat.sh. Should be clean now.

@haranrk haranrk assigned haranrk and unassigned rohityan Jun 17, 2026
@GWeale
GWeale self-requested a review July 15, 2026 18:05
@GWeale GWeale self-assigned this Jul 15, 2026
@GWeale

GWeale commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Appreciate this! Preserving JSON-native types in A2A metadata serialization is now handled in main, so this is covered. Closing as superseded, thanks so much for the work.

@GWeale GWeale closed this Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a2a [Component] This issue is related a2a support inside ADK. request clarification [Status] The maintainer need clarification or more information from the author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A2A _serialize_value() corrupts JSON-native metadata types to strings

4 participants