-
Notifications
You must be signed in to change notification settings - Fork 50
Description
[Bug]: FileWithBytes and FileWithUri use non-compliant field names (bytes/uri/mimeType instead of fileWithBytes/fileWithUri/mediaType)
Description
The A2A NuGet package v0.1.0-preview.2 uses non-compliant field names for file handling that do not match the official A2A Protocol Specification. This breaks interoperability with spec-compliant agents.
Specification Reference
Official A2A Protocol Specification:
- URL: https://a2a-protocol.org/latest/specification/
- Section: 4.1.7. FilePart
Exact Field Names from Specification (Section 4.1.7):
The specification defines FilePart with the following fields:
| Field Name | Type | Description |
|---|---|---|
fileWithUri |
string (optional) | URL pointing to file content |
fileWithBytes |
bytes (optional) | Base64-encoded file content |
mediaType |
string (optional) | File's media type (e.g., "application/pdf") |
name |
string (optional) | Optional filename (e.g., "document.pdf") |
Key Constraint from Specification:
"A FilePart MUST contain exactly one of the following:
fileWithUri,fileWithBytes"
Expected JSON Structure per Specification:
Example 1 - File with bytes:
{
"kind": "file",
"file": {
"fileWithBytes": "iVBORw0KGgoAAAANSUhEUgAAAAUA...",
"mediaType": "image/png",
"name": "input_image.png"
}
}Example 2 - File with URI:
{
"kind": "file",
"file": {
"fileWithUri": "https://storage.example.com/file.pdf",
"mediaType": "application/pdf",
"name": "document.pdf"
}
}Current SDK Implementation (NON-COMPLIANT)
SDK Types (decompiled from A2A.dll v0.1.0-preview.2):
FileWithBytes class:
namespace A2A;
public sealed class FileWithBytes : FileContent
{
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("mimeType")] // ❌ WRONG - Should be "mediaType"
public string? MimeType { get; set; }
[JsonPropertyName("bytes")] // ❌ WRONG - Should be "fileWithBytes"
[JsonRequired]
public string Bytes { get; set; } = string.Empty;
[JsonPropertyName("uri")] // ❌ WRONG - Should not exist
public string? Uri { get; set; }
}FileWithUri class:
namespace A2A;
public sealed class FileWithUri : FileContent
{
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("mimeType")] // ❌ WRONG - Should be "mediaType"
public string? MimeType { get; set; }
[JsonPropertyName("uri")] // ❌ WRONG - Should be "fileWithUri"
[JsonRequired]
public string Uri { get; set; } = string.Empty;
}Actual JSON Output from SDK:
Example 1 - FileWithBytes (NON-COMPLIANT):
{
"kind": "file",
"file": {
"kind": "bytes",
"name": "test.png",
"mimeType": "image/png",
"bytes": "iVBORw0KGgo...",
"uri": null,
"metadata": {}
}
}Example 2 - FileWithUri (NON-COMPLIANT):
{
"kind": "file",
"file": {
"kind": "uri",
"name": "document.pdf",
"mimeType": "application/pdf",
"uri": "https://example.com/document.pdf",
"metadata": {}
}
}Field Name Violations Summary
| SDK Field Name | SDK Location | Specification Field Name | Compliance Status |
|---|---|---|---|
file.bytes |
FileWithBytes.Bytes | file.fileWithBytes |
❌ Wrong name |
file.uri (in FileWithBytes) |
FileWithBytes.Uri | Should not exist | ❌ Extra field |
file.uri (in FileWithUri) |
FileWithUri.Uri | file.fileWithUri |
❌ Wrong name |
file.mimeType |
FileWithBytes/FileWithUri.MimeType | file.mediaType |
❌ Wrong name |
file.name |
FileWithBytes/FileWithUri.Name | file.name |
✅ Correct |
Impact
🔴 Interoperability Broken
- Spec-compliant agents expecting
fileWithByteswill not recognizebytes - Spec-compliant agents expecting
fileWithUriwill not recognizeuri - Spec-compliant agents expecting
mediaTypewill not recognizemimeType - Messages with file attachments will fail to deserialize on receiving end
🔴 Mutual Exclusivity Violation
- Both
FileWithBytesandFileWithUriclasses have bothBytesandUriproperties - Specification requires: "A FilePart MUST contain exactly one"
- SDK violates this by having both fields (set to null when unused)
🔴 Protocol Version Compliance
- A2A Protocol v1.0 (DRAFT) specifies these field names in Section 4.1.7
- SDK claims to implement A2A protocol but deviates from specification
- Creates fragmentation in A2A ecosystem
Reproduction / Test Evidence
Created integration tests that verify the JSON output from the SDK:
Test Code:
[Fact]
public void CreateUserMessage_WithFileUpload_ProducesCorrectJsonStructure()
{
var filePart = new FilePart
{
File = new FileWithBytes
{
Bytes = "SGVsbG8=",
MimeType = "text/plain"
}
};
var json = JsonSerializer.Serialize(filePart, JsonOptions);
var jsonDoc = JsonDocument.Parse(json);
var fileObj = jsonDoc.RootElement.GetProperty("file");
var hasFileWithBytes = fileObj.TryGetProperty("fileWithBytes", out _);
var hasBytes = fileObj.TryGetProperty("bytes", out _);
Assert.True(hasFileWithBytes,
"Field should be 'fileWithBytes' per A2A spec Section 4.1.7");
}Test Results:
❌ FAILED: CreateUserMessage_WithFileUpload_ProducesCorrectJsonStructure
Expected field: "fileWithBytes"
Actual field: "bytes"
COMPLIANCE FAILURE: Field should be 'fileWithBytes' per A2A v2 spec
(Section 4.1.7), but field not found. The A2A SDK may be using
non-compliant field names.
❌ FAILED: CreateUserMessage_WithFileUrl_ProducesCorrectJsonStructure
Expected field: "fileWithUri"
Actual field: "uri"
COMPLIANCE FAILURE: Field should be 'fileWithUri' per A2A v2 spec
(Section 4.1.7), but field not found.
Suggested Fix
Option 1: Update JsonPropertyName Attributes ⭐ (Recommended)
FileWithBytes.cs:
public sealed class FileWithBytes : FileContent
{
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("mediaType")] // ✅ Fixed
public string? MediaType { get; set; }
[JsonPropertyName("fileWithBytes")] // ✅ Fixed
[JsonRequired]
public string FileWithBytes { get; set; } = string.Empty;
// Remove Uri property entirely - ✅ Fixed
}FileWithUri.cs:
public sealed class FileWithUri : FileContent
{
[JsonPropertyName("name")]
public string? Name { get; set; }
[JsonPropertyName("mediaType")] // ✅ Fixed
public string? MediaType { get; set; }
[JsonPropertyName("fileWithUri")] // ✅ Fixed
[JsonRequired]
public string FileWithUri { get; set; } = string.Empty;
// Remove Bytes property entirely - ✅ Fixed
}Option 2: Custom JsonConverter (Non-Breaking)
Create JsonConverter<FileContent> that maps SDK properties to spec field names during serialization.
Option 3: New Major Version
Release v1.0.0 with breaking changes to align with specification.
Environment
- Package: A2A v0.1.0-preview.2 (NuGet)
- Target Framework: .NET 9.0
- Serializer: System.Text.Json
- OS: Windows 11
Related Issues
- [Bug]: FileContent deserialization is requiring a "kind" discriminator #183 - FileContent deserialization "kind" discriminator (CLOSED) - Related but different issue
- [Bug]: Specification is missing "kind" discriminator in
FileBaseobject hierarchy. A2A#1069 - Specification discussion about discriminators (OPEN)
Additional Context
This issue was discovered while implementing file attachment support in a Blazor WebAssembly A2A client application. The SDK successfully creates FilePart objects, but integration tests revealed the JSON output does not match the specification.
The field name mismatches prevent interoperability with:
- ✗ Spec-compliant A2A agents written in other languages (Python, Java, JS)
- ✗ Tools that validate A2A protocol compliance
- ✗ Future versions of the A2A ecosystem
Request: Please prioritize fixing this to ensure the .NET SDK produces specification-compliant output and maintains interoperability within the A2A ecosystem.
Specification References
-
A2A Protocol Specification v1.0 (DRAFT)
- URL: https://a2a-protocol.org/latest/specification/
- Section: 4.1.7. FilePart
- Direct quote: "A FilePart MUST contain exactly one of the following:
fileWithUri,fileWithBytes"
-
GitHub Specification
- https://github.com/a2aproject/A2A/blob/main/docs/specification.md
- Section: 4.1.7. FilePart
-
Other Official SDKs for Reference