Invalid parameter: messages with role 'tool' must be a response to a preceeding message with 'tool_calls'

Hi there! I’ve been having issues with something, I don’t know what it is. In the error message appears as “Bad request - please check your parametersInvalid parameter: messages with role ‘tool’ must be a response to a preceeding message with ‘tool_calls’.” Has something similar happend to you, I’m very stuck with this

Bad request - please check your parameters
Invalid parameter: messages with role ‘tool’ must be a response to a preceeding message with ‘tool_calls’.

Information on your n8n setup

  • n8n version: 2.30.6 (Self Hosted)
  • Database : PostgreSQL

Hi @Christian_G Welcome!
This happens when the chat history sent to the model has a tool message that isn’t directly preceded by an assistant message carrying its tool_calls, so the provider rejects the request. Your stored memory has gone out of sync for a session, usually from a run cut off mid tool call or a model swap, and since you’re on Postgres Chat Memory that broken history is saved and replayed on every run.
Clear that session’s memory. Quickest check: change the Session Key (or pass a new sessionId) and run again, the error should clear. To wipe the current session, connect a Chat Memory Manager node to the same Postgres Chat Memory, set Operation to Delete Messages and Delete Mode to All Messages, and run it once.

Hi Mr. Anshul, we will apply your recomendations an we’ll tell you how it works.
Thank you so much for your quick response​:folded_hands:.

Inspect the message array at the failed execution and pair each tool response with the assistant tool call that created it. Filtering or merging chat history can leave a tool message orphaned even when the current prompt looks fine.

Building on @Anshul_Namdev 's point: the root cause of this error in n8n AI Agents is usually **Window Buffer Memory Truncation**.

OpenAI’s API strictly requires that any message with `role: “tool”` MUST immediately follow an `assistant` message containing the matching `tool_calls` ID array.

Here is how this happens in n8n and how to prevent it permanently:

### The Root Cause:

If you use a **Window Buffer Memory** (or Postgres Memory) set to keep e.g. the last `10` messages:

1. An assistant message generates a `tool_call`.

2. The tool node executes and appends a `tool` response message.

3. As conversation progresses and reaches 11 messages, the Memory node drops the oldest message.

4. If the truncation split cuts off the `assistant` message with `tool_calls` but leaves the `tool` response message at the top of the history window, the payload sent to OpenAI becomes invalid.

### How to Fix It:

1. **Use `Window Buffer Memory` with Even Message Counts (or Increase K):**

Ensure your memory buffer size `K` is large enough so active tool-call pairs aren’t truncated mid-session.

2. **Clear Stale Sessions via `Chat Memory Manager`:**

If a session gets stuck with this error, use a **Chat Memory Manager Node** set to `Delete Messages` for that specific `sessionId`.

3. **Handle Tool Failures (Error Trigger / Sub-Workflow):**

If an MCP or Custom Tool fails mid-execution, wrap the tool logic in a `Try/Catch` or `Continue on Fail` setting so it always returns a valid JSON string payload to the agent instead of dropping the socket and corrupting the memory history.