Category: Bug Report / Feature Request
I’m encountering a race condition issue when using parallel tool calls in LangGraph that results in OpenAI API errors. The problem occurs when tool responses arrive out of order compared to their corresponding tool calls.
The Problem
When an AI message contains multiple tool calls (executed in parallel), the tool responses sometimes get inserted into the message history in the wrong order. This causes OpenAI’s API to reject the conversation with:
Error code: 400 - {'error': {'message': "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_Yf5XYJgBqChJCDqQOYZb84t4", 'type': 'invalid_request_error', 'param': 'messages.[4].role', 'code': None}}
Example Scenario
-
AI makes two parallel tool calls:
call_Aandcall_B -
Due to timing differences, the response for
call_Barrives first -
LangGraph appends it to the message history
-
An AI message from a different agent gets inserted
-
Then the response for
call_Aarrives and gets appended -
Now the tool calls and responses are no longer consecutive, violating OpenAI’s requirements
Current Workaround Attempts
I see three potential solutions:
-
Framework Fix: Have LangGraph automatically handle tool response ordering/grouping
-
Custom Reducer: Implement a reducer that intelligently places tool responses adjacent to their corresponding tool calls
-
Disable Parallel Tool Calls: Force sequential execution (but this hurts performance)
Question for the Community
Has anyone else encountered this issue? What’s the recommended approach for handling this in LangGraph?
Would the LangGraph team consider:
-
Adding built-in support for keeping tool calls and responses grouped together?
-
Providing an option to disable parallel tool execution?
-
Adding a reducer utility that handles tool response ordering automatically?
Code Context
The issue manifests when using multiple agents that can send messages to each other while tool calls are still pending, causing the message order to become:
AI_message_with_tool_calls -> tool_response_1 -> different_AI_message -> tool_response_2
Instead of the required:
AI_message_with_tool_calls -> tool_response_1 -> tool_response_2 -> different_AI_message
Any guidance would be appreciated!