Skip to content

[Bug] 400 Unexpected role 'user' after role 'tool' when handoff follows a tool call #54

Description

@JumpLink

What happens
When an agent runs a tool (e.g. list_upload_sessions) and then hands off to another agent in the same turn, the request can fail with:

400 Unexpected role 'user' after role 'tool'

Image

Why
For the receiving agent, handoff instructions are added as a HumanMessage (user role). If the last message in the filtered history is a ToolMessage (from the tool the router just ran), the sequence becomes … tool → user. Many chat APIs require an assistant turn after a tool message, so they reject this order.

When it appears
Only when the router runs a non-handoff tool and then does a handoff. If the router hands off without running another tool first, the last message is not a tool message and the error does not occur.

Suggested fix
When building messages for the receiving agent, if the last message in filteredMessages is already a ToolMessage, append the handoff instructions to that message’s content instead of adding a new HumanMessage. That keeps the sequence as … tool (with instructions in the tool message) and the next step is the assistant (receiving agent), which is valid.

Steps to reproduce

  1. Start with Universal (or any router that can call tools and hand off).
  2. Ask for something that triggers a tool call and then a handoff (e.g. “I want to visualize CSV data, please provide an upload” → router runs list_upload_sessions, then transfers to Data Analysis).
  3. After the transfer, the 400 error can appear.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions