-
Notifications
You must be signed in to change notification settings - Fork 358
Description
What happened?
_clean_empty in src/a2a/utils/helpers.py is documented to "recursively remove empty strings, lists and dicts". The base case correctly targets only '', [], {}, but the dict and list filters use truthiness (if v) which also drops 0, False, and 0.0:
return {k: v for k, v in cleaned_dict.items() if v} # drops 0, False, 0.0
return [v for v in cleaned_list if v] # drops 0, False, 0.0
return d if d not in ['', [], {}] else None # correctThis affects canonicalize_agent_card() (the only caller), which produces canonical JSON for signature verification (RFC 8785). An AgentCard with e.g. AgentCapabilities(streaming=False) would have the field stripped after surviving model_dump(exclude_none=True), losing the distinction between "explicitly disabled" and "unspecified".
Reproduction:
from a2a.utils.helpers import _clean_empty
assert _clean_empty({"retries": 0}) == {} # expected: {"retries": 0}
assert _clean_empty({"enabled": False}) == {} # expected: {"enabled": False}
assert _clean_empty([0, 1, 2]) == [1, 2] # expected: [0, 1, 2]Suggested fix — align filters with the base case:
return {k: v for k, v in cleaned_dict.items() if v is not None}
return [v for v in cleaned_list if v is not None]If this behavior is intentional, I may be missing some context — in that case, clarifying the docstring and base case to better reflect the current filtering semantics could help avoid confusion.
If it’s considered a bug, I’d be glad to open a PR with the proposed change and add regression tests as needed.
Relevant log output
No output — values are dropped silently.Code of Conduct
- I agree to follow this project's Code of Conduct