Skip to content

[dotnet-port-fixes] fix(a2a): reject outbound messages without sendable content - #1303

Merged
Quim Muntal (qmuntal) merged 1 commit into
mainfrom
dotnet-port/a2a-empty-message-validation-b87d0c0679e50417
Oct 19, 2026
Merged

Quim Muntal (qmuntal) merged 1 commit into
mainfrom
dotnet-port/a2a-empty-message-validation-b87d0c0679e50417

Conversation

@microsoft-agent-framework-for-go

Copy link
Copy Markdown
Contributor

Summary

Port the pinned .NET A2A validation fix to the Go outbound A2A provider. Requests whose messages contain no convertible A2A parts now return an error before any transport call, including empty message lists, empty text, empty contents, and unsupported contents.

Ported .NET PRs

Pinned upstream revision: ebcf4db7f9462ef6c377761e0b3159c4c5a73027.
Inspected recent groups: A2A validation commit 44fe223da7ea6853eefb7053e25c2c213a2e5c15 (source) and AG-UI resolver ordering commit 501cc6f6c702d444caabe8e1aba1732f9bc3bc3f (source). The selected A2A change is fix-only under the existing Go API; the AG-UI change was excluded because Go delegates serialization to the external AG-UI SDK rather than configuring ASP.NET resolver chains.

Duplicate checks used the fixed issue query repo:microsoft/agent-framework-go A2A empty message parts no content send request validation and PR query repo:microsoft/agent-framework-go A2A messagesToA2AMessage empty parts validation, before and after editing. The issue search surfaced filtered microsoft/agent-framework-go#540; its direct read showed only an already-merged helper extraction and no overlap with this validation fix. The PR query returned no results.

Breaking Changes

No. This corrects invalid outbound requests by returning an error before the remote A2A service is called.

Tests and Examples

  • go test ./provider/a2aprovider
  • git diff --check
  • Added black-box coverage for empty messages, empty contents, empty text, unsupported contents, and both streaming and non-streaming runs; assertions verify no transport call occurs.

Notes

Go changes are limited to provider/a2aprovider/a2a.go and provider/a2aprovider/a2a_test.go. No public API, configuration, default, generated file, binary, or build artifact was added.

Warning

Firewall blocked 3 domains

The following domains were blocked by the firewall during workflow execution:

  • proxy.golang.org
  • storage.googleapis.com
  • sum.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"
    - "storage.googleapis.com"
    - "sum.golang.org"

See Network Configuration for more information.

Generated by .NET to Go Fixes and Test Porting Agent · copilot · gpt56 · 4.49 AIC · ⌖ 0.975 AIC · ⊞ 24.9K · ◷

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added area:provider Changes files in the provider area area:provider/a2a Changes files in the provider / a2a area size:medium At most 100 changed lines across at most 5 files kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure parity-approved Go API consistency review found no parity issues labels Oct 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

API consistency review

Result Scope
aligned user-visible behavior

Changed Go contract

provider/a2aprovider run/messagesToA2AMessage: previously, calling Run with zero messages silently returned no updates, while non-empty messages that produced no sendable Parts (e.g. empty text, unsupported content types) were sent to the remote agent anyway. The PR removes the early len(messages) == 0 short-circuit and instead rejects any request whose combined content parts are empty — for both empty and non-empty message slices — with errors.New("a2aprovider: the provided messages contain no content that can be sent to the remote agent"), and verifies no A2A transport call occurs. No new exported symbols are introduced.

Upstream evidence reviewed

Implementation Source Contract checked
.NET CreateA2AMessage in A2AAgent.cs Throws ArgumentException("The provided messages contain no content that can be sent to the remote agent.", nameof(messages)) whenever a2aMessage.Parts.Count == 0, regardless of whether messages was empty or merely devoid of convertible content.
Python _prepare_message_for_a2a in _agent.py and run in _agent.py Raises ValueError("Message.contents is empty; cannot convert to A2AMessage.") for empty contents, and AgentInvalidRequestException when normalized_messages is empty and no continuation token is supplied.

Assessment

Both upstream implementations already reject requests that resolve to no sendable content, using wording functionally identical to the new Go error. This PR brings Go into parity by replacing the previous silent no-op on empty messages with an explicit error covering both the empty-slice and empty-content-after-conversion cases, matching .NET's Parts.Count == 0 check and Python's content-emptiness validation. No divergence found; behavior, trigger condition, and surfaced error semantics are aligned across all three implementations.

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • github.com
  • raw.githubusercontent.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"
    - "raw.githubusercontent.com"

See Network Configuration for more information.

Generated by Go API Consistency Review Agent for #1303 · copilot · auto · 53.2 AIC · ⌖ 7.16 AIC · ⊞ 13.9K · ◷

@qmuntal
Quim Muntal (qmuntal) marked this pull request as ready for review October 19, 2026 03:43
@qmuntal
Quim Muntal (qmuntal) requested a review from a team as a code owner October 19, 2026 03:43
Copilot AI balanced review requested due to automatic review settings October 19, 2026 03:43

Copilot AI 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.

🟢 Approval recommended

The focused validation covers both send modes, preserves continuation handling, and has no identified blocking issues.

No open issues 🎉

What changed in this PR

Adds outbound A2A validation so messages without sendable content fail before contacting the remote agent.

Changes:

  • Rejects empty message lists and messages with no convertible A2A parts.
  • Adds regression coverage for streaming and non-streaming requests, verifying no transport calls occur.
File Description
provider/​a2aprovider/​a2a.go Rejects requests without sendable content.
provider/​a2aprovider/​a2a_test.go Tests rejection cases and absence of transport calls.

Review effort: Balanced

Merged via the queue into main with commit c679296 Oct 19, 2026
35 checks passed
@qmuntal
Quim Muntal (qmuntal) deleted the dotnet-port/a2a-empty-message-validation-b87d0c0679e50417 branch October 19, 2026 03:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:provider/a2a Changes files in the provider / a2a area area:provider Changes files in the provider area kind:code Changes production behavior or code kind:tests Changes tests, fixtures, or test infrastructure parity-approved Go API consistency review found no parity issues size:medium At most 100 changed lines across at most 5 files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants