Bug: Remote invoke for invocations-protocol agents silently falls back to responses endpoint, fails with invalid_payload
Describe the bug
When running azd ai agent invoke against a deployed invocations-protocol agent, the remote invoke path silently falls through to the responses handler, which:
- Posts to
{endpoint}/agents/{name}/endpoint/protocols/openai/responses instead of the invocations endpoint
- Includes a
"conversation": {"id": ...} property in the request body
- The endpoint-scoped responses API rejects this with HTTP 400:
Endpoint-scoped response APIs are stateless and do not support conversation context. Remove the 'conversation' property.
This affects all invocations-protocol templates when vnext is enabled and protocol resolution falls back to the default (responses).
To reproduce
- Deploy a hosted agent using an invocations-protocol template (e.g., Multi-Turn Chat Python /invocations from
hosted-agents-vnext-private-preview/samples/)
- Run:
azd ai agent invoke multiturn-chat-invocations "My name is Alice and my favorite color is blue."
- Observe HTTP 400 error with
invalid_payload
Expected behavior
The invoke command should detect that the deployed agent uses the invocations protocol and route through invocationsRemote(), not responsesRemote().
Root cause (from source analysis of PR #7422)
In invoke.go, the Run() method dispatches like this:
if isVNextEnabled(ctx) {
protocol := a.resolveRemoteProtocol(ctx)
if protocol == agent_api.AgentProtocolInvocations {
return a.invocationsRemote(ctx)
}
}
return a.responsesRemote(ctx)
resolveRemoteProtocol() calls resolveAgentProtocol() (in helpers.go), which:
- Resolves the agent service from
azure.yaml
- Reads the local
agent.yaml manifest from the service directory
- Returns the first protocol listed, defaulting to
AgentProtocolResponses on any error
Failure mode: If the agent name passed to azd ai agent invoke <name> "message" does not match a service in the local azure.yaml, resolveAgentService() fails, protocol defaults to responses, and the request routes through responsesRemote().
Additionally, responsesRemote() with vnext enabled always includes "conversation": {"id": convID} in the body, but the endpoint-scoped responses API is stateless and rejects this property.
Suggested fixes
- Primary: Select
invocationsRemote() based on the deployed agent manifest (server-side), not just the local agent.yaml
- Secondary:
responsesRemote() with vnext should not include conversation for endpoint-scoped responses APIs (stateless APIs reject it)
- Defensive: Log a warning when protocol resolution fails instead of silently defaulting to responses
Related issues
Environment
- azd version: azure.ai.agents extension v0.1.20-preview (2026-04-02)
- OS: Linux (Ubuntu)
- Region: northcentralus
- Template: Multi-Turn Chat Python /invocations (hosted-agents-vnext-private-preview samples)
Additional context
Trace ID: f1855e1f-9508-4bb4-bafb-64822547d6d6
Request ID: 81d218c0d235edbb17c342d7d39ba14c
Bug: Remote invoke for invocations-protocol agents silently falls back to responses endpoint, fails with
invalid_payloadDescribe the bug
When running
azd ai agent invokeagainst a deployed invocations-protocol agent, the remote invoke path silently falls through to the responses handler, which:{endpoint}/agents/{name}/endpoint/protocols/openai/responsesinstead of the invocations endpoint"conversation": {"id": ...}property in the request bodyEndpoint-scoped response APIs are stateless and do not support conversation context. Remove the 'conversation' property.This affects all invocations-protocol templates when vnext is enabled and protocol resolution falls back to the default (responses).
To reproduce
hosted-agents-vnext-private-preview/samples/)azd ai agent invoke multiturn-chat-invocations "My name is Alice and my favorite color is blue."invalid_payloadExpected behavior
The invoke command should detect that the deployed agent uses the invocations protocol and route through
invocationsRemote(), notresponsesRemote().Root cause (from source analysis of PR #7422)
In
invoke.go, theRun()method dispatches like this:resolveRemoteProtocol()callsresolveAgentProtocol()(inhelpers.go), which:azure.yamlagent.yamlmanifest from the service directoryAgentProtocolResponseson any errorFailure mode: If the agent name passed to
azd ai agent invoke <name> "message"does not match a service in the localazure.yaml,resolveAgentService()fails, protocol defaults toresponses, and the request routes throughresponsesRemote().Additionally,
responsesRemote()with vnext enabled always includes"conversation": {"id": convID}in the body, but the endpoint-scoped responses API is stateless and rejects this property.Suggested fixes
invocationsRemote()based on the deployed agent manifest (server-side), not just the localagent.yamlresponsesRemote()with vnext should not includeconversationfor endpoint-scoped responses APIs (stateless APIs reject it)Related issues
invoke#7492 — Adding a--protocolflag toazd ai agent invokewould serve as a user-facing workaroundazd ai agent invokeworks with the invocations protocol #7431 — Original invocations protocol support (closed)Environment
Additional context
Trace ID:
f1855e1f-9508-4bb4-bafb-64822547d6d6Request ID:
81d218c0d235edbb17c342d7d39ba14c