When the loop will not stop
The loop ends when the model replies with a finished answer instead of another tool request. A model that only ever asks for tools would go round forever, so the SDK counts.
A model that never finishes
Scripting one reply and nothing else means the model repeats it every turn, which is exactly the failure worth seeing on purpose.
stuck = PretendModel([call("lookup_order", order_id="A17")])
agent = Agent(name="Support", instructions="x", model=stuck, tools=[lookup_order])Run it with a small limit
try:
await Runner.run(agent, "Where is order A17?", max_turns=3)
except MaxTurnsExceeded as e:
print("stopped:", e)try:
await Runner.run(agent, "Where is order A17?", max_turns=3)
except MaxTurnsExceeded as e:
print("stopped:", e)A turn is one trip to the model. Three turns, three requests for the same tool, no final answer, so the run is abandoned and you get MaxTurnsExceeded.
What counts as finished
The docs are exact about this, and it is worth being exact too. A reply ends the loop when it is text, of the type you asked for, and carries no tool calls. All three. A message with words and a tool request in it is not an answer, it is another turn.
That third condition matters more than it first looks. Lesson 10 shows how to ask for an answer in a fixed shape, and once you have, a reply that does not fit that shape is not final either. The loop carries on rather than handing you something wrong.
max_turns=None turns the limit off entirely. There are real uses for that, and none of them are on a first agent talking to customers.What to do when you see it
Raising the limit is almost never the fix. The error is telling you the agent cannot make progress, and a bigger number only delays the same ending.
- Look at what it kept asking for. Usually one tool whose answer does not actually satisfy the question.
- Read the tool's description. If it promises more than it returns, the model will keep trying.
- Check the instructions. An agent told to keep looking until it is certain will do exactly that.
- Set the limit to 10 and confirm the message changes but the ending does not.
- Add a second reply so the model answers with words on turn two, and watch it finish.
- Remove
max_turnsentirely and see how long it goes.
Every expert started right here.