Skip to content

PartConverter.toGenaiPart() unconditionally sets Part.Builder#partMetadata(), which the GenAI SDK rejects on Vertex AI / Gemini Enterprise Agent Platform #1421

Description

Describe the bug

com.google.adk.a2a.converters.PartConverter#toGenaiPart (and its TextPart / FilePart / DataPart branches) unconditionally forwards the source A2A part's metadata into Part.Builder#partMetadata(Map) whenever it is non-null (TextPart) or non-empty (FilePart, DataPart). The Google GenAI Java SDK rejects that field outside of Gemini Developer API mode:

partMetadata parameter is only supported in Gemini Developer API mode, not in Gemini Enterprise Agent Platform mode

This isn't limited to callers who intentionally attach custom part metadata. PartConverter.fromGenaiPart() (the reverse, GenAI->A2A direction) always attaches a metadata map to every A2A part it produces - even an empty one, used to carry isPartial / thought - so any GenAI Part that has round-tripped through an ADK-based A2A peer comes back into toGenaiPart() with a metadata map attached. In practice this breaks essentially every inbound A2A message/response once the receiving agent is configured for Vertex AI / Enterprise Agent Platform mode instead of Developer API mode.

Environment

  • google-adk-a2a: confirmed present from 1.5.0
  • GenAI backend: Vertex AI / Gemini Enterprise Agent Platform (not reproducible against Gemini Developer API mode)

To Reproduce

  1. Configure a Google ADK Java agent against Vertex AI / Gemini Enterprise Agent Platform (as opposed to Gemini Developer API mode).
  2. Expose it as an A2A agent, or call it through RemoteA2AAgent / AgentExecutor.
  3. Send any A2A message — a plain TextPart is enough, since ADK peers always attach a metadata map.
  4. PartConverter.toGenaiPart() calls Part.Builder#partMetadata(...), and the GenAI SDK throws IllegalArgumentException:
    partMetadata parameter is only supported in Gemini Developer API mode, not in Gemini Enterprise Agent Platform mode.

Expected behavior

PartConverter should either:

  • skip .partMetadata(...) when the active GenAI backend doesn't support it, or
  • expose a way to opt out (an AgentExecutorConfig flag, a system property, etc.), or
  • catch/ignore the SDK's rejection instead of letting it fail the whole part conversion.

Root cause / affected locations

File: a2a/src/main/java/com/google/adk/a2a/converters/PartConverter.java

// line 90 — TextPart
if (textPart.getMetadata() != null) {
  partBuilder.partMetadata(textPart.getMetadata());   // unconditional
  ...
}

// line 126 — FilePart / FileWithUri
if (metadata != null) {
  builder.partMetadata(metadata);                      // unconditional
}

// line 141 — FilePart / FileWithBytes
if (metadata != null) {
  builder.partMetadata(metadata);                      // unconditional
}

// lines 167, 186, 202, 220, 234 — DataPart
// (function call / function response / executable code / code execution result / generic fallback)
if (!metadata.isEmpty()) {
  builder.partMetadata(metadata);                      // unconditional
}

None of these call sites check which GenAI backend/mode is active before calling .partMetadata(...).

Metadata

Metadata

Assignees

Labels

waiting on reporterWaiting for reaction by reporter. Failing that, maintainers will eventually closed it as stale.

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions