A prompt triggering multiple tool calls at once, produces a history from the frontend like:
assistant(tool_call: call_1)
assistant(tool_call: call_2)
assistant(tool_call: call_3)
tool_result(call_1)
tool_result(call_2)
tool_result(call_3)
When this history is sent back to the model on the next turn (additional user message), the OpenAI tools protocol rejects it:
System.ClientModel.ClientResultException: HTTP 400
(invalid_request_error: )
Parameter: messages.[3].role
An assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'. The following tool_call_ids did not have response messages: call_8oepC2nxsf2P1h7CYhIlBBmK at
OpenAI.ClientPipelineExtensions.ProcessMessageAsync(ClientPipeline pipeline, PipelineMessage message, RequestOptions options)
at OpenAI.Chat.ChatClient.CompleteChatAsync(BinaryContent content, RequestOptions options)
at OpenAI.Chat.ChatClient.<>c__DisplayClass19_0.
<<CompleteChatStreamingAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
In other words, each assistant message that performs a tool call must be immediately followed by its matching tool result.
The correct sequence should look like:
assistant(tool_call: call_1)
tool_result(call_1)
assistant(tool_call: call_2)
tool_result(call_2)
assistant(tool_call: call_3)
tool_result(call_3)
A prompt triggering multiple tool calls at once, produces a history from the frontend like:
When this history is sent back to the model on the next turn (additional user message), the OpenAI tools protocol rejects it:
In other words, each assistant message that performs a tool call must be immediately followed by its matching tool result.
The correct sequence should look like: