Skip to content

.NET: [Bug]: Foundry Responses API based agents fail in Workflows when Foundry hosted tools are used. #5338

@tarockey

Description

@tarockey

Description

When AgentWorkflowBuilder.BuildSequential chains two Foundry-backed agents, the workflow forwards the complete output[] stream from agent A as the input[] for agent B's POST /openai/v1/responses call, including Foundry server-side output items such as mcp_list_tools, web_search_call, reasoning, etc. Foundry's Responses API rejects those items on the hand-off:

 {
   "error": {
     "code": "invalid_payload",
     "message": "The provided data does not match the expected schema",
     "param": "/",
     "type": "invalid_request_error",
     "details": [],
     "additionalInfo": { "request_id": "055bb009413af220ba1c4166d1254ffd" }
   }
 }

This breaks any AF workflow that chains two or more Foundry-backed agents where any upstream agent has any Foundry-hosted tool attached (WebSearchTool, FileSearchTool, CodeInterpreterTool, McpTool, FabricDataAgentTool,
etc.).

To verify this, I have tested calling Foundry-hosted (but unpublished) agents with no tools, published agents with no tools, and unpublished agents with locally defined tools - no errors in any of these cases.

Observed sequence:

  1. Agent a1 → POST /openai/v1/responses with tools:[WebSearchTool] → 200 OK, streams response.completed with
    output[] containing web_search_call, reasoning, and message(output_text) items.
  2. Agent a2 → POST /openai/v1/responses → 400 Bad Request invalid_payload.

Request body sent to agent a2 (redacted, preserving structure)

 {
   "input": [
     { "type": "message", "role": "user",
       "content": [{ "type": "input_text", "text": "Look up insurance fraud ..." }] },
 
     { "type": "web_search_call",
       "id": "ws_...",
       "status": "completed",
       "action": { "type": "search", "query": "..." },
       "agent_reference": { "type": "agent_reference", "name": "a1", "version": "..." },
       "response_id": "resp_..." },
 
     { "type": "reasoning", "id": "rs_...",
       "agent_reference": { "type": "agent_reference", "name": "a1", "version": "..." },
       "response_id": "resp_...", "summary": [] },
 
     { "type": "message", "role": "assistant",
       "content": [{ "type": "output_text", "text": "..." }] }
   ],
   "stream": true,
   "agent_reference": { "type": "agent_reference", "name": "a2", "version": "..." }
 }

Response:

400 Bad Request
apim-request-id: 2b2712d0-37bf-43f8-9bbe-d2000bde83d6
x-ms-region: East US

{
"error": {
"code": "invalid_payload",
"message": "The provided data does not match the expected schema",
"param": "/",
"type": "invalid_request_error"
}
}

Potential fix:

AgentWorkflowBuilder.BuildSequential (and any other chaining builder that crosses agent boundaries) should sanitize
the output[] of each stage before feeding it as input[] to the next stage. Minimum fix:

  • Drop any non-message items: mcp_list_tools, mcp_call, mcp_approval_request, mcp_approval_response, reasoning,
    web_search_call, file_search_call, code_interpreter_call, fabric_dataagent_preview_call, image_generation_call,
    computer_tool_call, and any future server-side call/output items.
  • Strip agent_reference and response_id from any forwarded item — those are scoped to the producing response and
    invalid on a cross-agent call.
  • Alternatively, surface a first-class extension point (e.g. .WithInterAgentInputFilter(...)) so consumers can
    configure the hand-off contract.

Code Sample

extern alias FoundryAlias;
 using Azure.AI.Projects;
 using Azure.Identity;
 using Microsoft.Agents.AI;
 using Microsoft.Agents.AI.Workflows;
 using Microsoft.Extensions.AI;
 using OpenAI.Responses;
 using FoundryExtensions = FoundryAlias::Azure.AI.Projects.AzureAIProjectChatClientExtensions;
 using FoundryAITool    = FoundryAlias::Microsoft.Agents.AI.Foundry.FoundryAITool;
 
 var client = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential());
 
 // WebSearchTool: Foundry-hosted, no config, emits `web_search_call` output items.
 IList<AITool> tools = [FoundryAITool.FromResponseTool(new WebSearchTool())];
 
 var a1 = FoundryExtensions.AsAIAgent(client,
     model: "gpt-5.4-mini",
     instructions: "Use web search to look up something relevant, then summarize briefly.",
     name: "a1", description: null, tools: tools);
 
 var a2 = FoundryExtensions.AsAIAgent(client,
     model: "gpt-5.4-mini",
     instructions: "Summarize the prior agent's output in one sentence.",
     name: "a2", description: null, tools: tools);
 
 var workflow = AgentWorkflowBuilder.BuildSequential([a1, a2]);
 
 await using var run = await InProcessExecution.RunStreamingAsync(
     workflow, new ChatMessage(ChatRole.User, "Look up insurance fraud patterns for rear-end collisions."));
 await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
 
 await foreach (var evt in run.WatchStreamAsync()) { /* observe */ }

Error Messages / Stack Traces

{
   "error": {
     "code": "invalid_payload",
     "message": "The provided data does not match the expected schema",
     "param": "/",
     "type": "invalid_request_error",
     "details": [],
     "additionalInfo": { "request_id": "055bb009413af220ba1c4166d1254ffd" }
   }
 }
ERROR: System.Reflection.TargetInvocationException: Error invoking handler for Microsoft.Agents.AI.Workflows.TurnToken
 ---> System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at Microsoft.Extensions.AI.ChatResponseExtensions.CoalesceWebSearchToolCallContent(IList`1 contents)
   at Microsoft.Extensions.AI.ChatResponseExtensions.CoalesceContent(IList`1 contents)
   at Microsoft.Extensions.AI.ChatResponseExtensions.FinalizeResponse(ChatResponse response)
   at Microsoft.Extensions.AI.ChatResponseExtensions.ToChatResponse(IEnumerable`1 updates)
   at Microsoft.Agents.AI.AgentResponseExtensions.ToAgentResponse(IEnumerable`1 updates)
   at Microsoft.Agents.AI.Workflows.Specialized.AIAgentHostExecutor.InvokeAgentAsync(IEnumerable`1 messages, IWorkflowContext context, Boolean emitEvents, CancellationToken cancellationToken)
   at Microsoft.Agents.AI.Workflows.Specialized.AIAgentHostExecutor.ContinueTurnAsync(List`1 messages, IWorkflowContext context, Boolean emitEvents, CancellationToken cancellationToken)
   at Microsoft.Agents.AI.Workflows.ChatProtocolExecutor.<>c__DisplayClass13_0.<<TakeTurnAsync>g__InvokeTakeTurnAsync|0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.Agents.AI.Workflows.StatefulExecutor`1.InvokeWithStateAsync(Func`4 invocation, IWorkflowContext context, Boolean skipCache, CancellationToken cancellationToken)
   at Microsoft.Agents.AI.Workflows.RouteBuilder.<>c__DisplayClass12_0`1.<<AddHandler>g__WrappedHandlerAsync|0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.Agents.AI.Workflows.Execution.MessageRouter.RouteMessageAsync(Object message, IWorkflowContext context, Boolean requireRoute, CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at Microsoft.Agents.AI.Workflows.Executor.ExecuteCoreAsync(Object message, TypeId messageType, IWorkflowContext context, WorkflowTelemetryContext telemetryContext, CancellationToken cancellationToken)
   at Microsoft.Agents.AI.Workflows.InProc.InProcessRunner.DeliverMessagesAsync(String receiverId, ConcurrentQueue`1 envelopes, CancellationToken cancellationToken)
   at Microsoft.Agents.AI.Workflows.InProc.InProcessRunner.DeliverMessagesAsync(String receiverId, ConcurrentQueue`1 envelopes, CancellationToken cancellationToken)
   at Microsoft.Agents.AI.Workflows.InProc.InProcessRunner.RunSuperstepAsync(StepContext currentStep, CancellationToken cancellationToken)
   at Microsoft.Agents.AI.Workflows.InProc.InProcessRunner.Microsoft.Agents.AI.Workflows.Execution.ISuperStepRunner.RunSuperStepAsync(CancellationToken cancellationToken)

Package Versions

Microsoft.Agents.AI 1.1.0, Microsoft.Agents.AI.Workflows 1.1.0, Microsoft.Agents.AI.Foundry 1.1.0 , Azure.AI.Projects 2.0.0, Azure.Identity 1.20.0

.NET Version

.NET 10.0

Additional Context

I've been testing this with tools such as the Web Search tool, and WorkIQ MCP tools, all failing in the same way.

Foundry endpoint api-version=v1 (supported: 1.0, 2025-05-15-preview, 2025-11-15-preview) , Model: gpt-5.4-mini

Metadata

Metadata

Assignees

Labels

Type

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions