Skip to content

fix(compat): send v0.3 REST request bodies with json_name keys - #1455

Merged
Iwaniukooo11 merged 2 commits into
a2aproject:mainfrom
ConnorMoss02:fix/v03-rest-json-names
Nov 13, 2026
Merged

Iwaniukooo11 merged 2 commits into
a2aproject:mainfrom
ConnorMoss02:fix/v03-rest-json-names

Conversation

@ConnorMoss02

Copy link
Copy Markdown
Contributor

Fixes #1454

Drops preserving_proto_field_name=True from the three MessageToDict calls (send, stream, push config create), so the body uses json_name keys like the spec requires.

Against a2a-go's v0.3 server, a send went from 400 "message is required" to 200 with the agent's reply.

The three new tests in test_rest_transport.py fail on main. The cross-version tests against a2a-sdk 0.3.24 still pass.

The compat REST client serialized send, stream and push config create
bodies with preserving_proto_field_name=True, so it sent "request" and
"message_id" instead of "message" and "messageId". The v0.3 spec
requires json_name keys for HTTP+JSON, and a2a-sdk 0.3.x sent them.
Servers that only read json_name keys, like a2a-go's v0.3 REST server,
reject every send with 400 "message is required". Use the default
MessageToDict, which a2a-python's own v0.3 REST server already accepts.
@ConnorMoss02
ConnorMoss02 requested a review from a team as a code owner November 12, 2026 15:45
@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

🧪 Code Coverage (vs main)

⬇️ Download Full Report

Base PR Delta
src/a2a/server/cluster/database_event_stream.py 97.27% 93.64% 🔴 -3.64%
Total 93.63% 93.59% 🔴 -0.04%

Generated by coverage-comment.yml

@1AbdullahButt 1AbdullahButt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks correct. Here's what I checked.

  • Older a2a-python v0.3 servers still accept the new bodies. CompatRestHandler.on_message_send and set_push_notification (compat/v0_3/rest_handler.py:72 and :214) read the body with parse_lenient into the v0.3 proto. The protobuf JSON parser accepts both the json_name and the original field name (ProtoJSON format: "Protobuf JSON parsers are required to accept both the converted lowerCamelCase name and the proto field name"). So switching from request/message_id to message/messageId doesn't break this SDK's own server. The cross-version tests in the description are consistent with that.
  • SendMessageRequest.request is renamed to message. That comes from json_name in a2a_v0_3.proto. The serialized descriptor has R\x07message on field 1, so 'request' not in sent is the right assertion.
  • There are no other spots to change. The only other request-building paths in rest_transport.py already used camelCase by hand (params['historyLength'] at :162) or send no body. Responses are read with ParseDict(..., ignore_unknown_fields=True), which accepts either naming.
  • git merge-tree against main is clean.

One question for a follow-up, not a blocker. The v0.3 CreateTaskPushNotificationConfig HTTP rule has body: "config" (visible in the serialized descriptor in a2a_v0_3_pb2.py). Under standard gRPC-HTTP transcoding, the POST body is then only the TaskPushNotificationConfig, not the whole request with parent/configId. This client sends the whole request, and this SDK's server parses the whole request, so the two agree with each other. A server that transcodes strictly from the proto (a2a-go may be one) would look for pushNotificationConfig at the top level, so push config create could still fail there after this PR. I haven't checked a2a-go's handler. If you have the a2a-go setup from the description handy, a push-config create against it would settle the question.

I didn't run the tests.

Reviewed with help from Claude Code.

@Iwaniukooo11 Iwaniukooo11 self-assigned this Nov 13, 2026

@Iwaniukooo11 Iwaniukooo11 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Iwaniukooo11
Iwaniukooo11 merged commit 2399993 into a2aproject:main Nov 13, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

v0.3 REST client sends snake_case field names, so a2a-go rejects every send

3 participants