How to Fix 'agent infinite loop in production' in AutoGen (TypeScript)
If you’re seeing agent infinite loop in production, your AutoGen agent is almost always failing to reach a terminal state. In practice, that means the model keeps producing tool calls, retries, or self-referential replies until your runtime hits a max-iteration guard, timeout, or custom loop detector.
In AutoGen TypeScript, this usually shows up when an agent never emits a final answer, a tool result keeps re-triggering the same planner step, or your message routing sends the same event back into the same agent chain.
The Most Common Cause
The #1 cause is a missing termination condition in an agent loop. In AutoGen TS, this often happens when you keep calling run() or onMessages() without checking whether the assistant has already produced a final response.
Here’s the broken pattern:
| Broken | Fixed |
|---|---|
| Keeps re-invoking the agent with no exit check | Stops when the assistant returns a final answer |
// Broken: endless re-entry into the same agent flow
import { AssistantAgent } from "@autogen/agents";
const agent = new AssistantAgent({
name: "support-agent",
systemMessage: "Help the user and use tools when needed.",
});
async function handleRequest(input: string) {
let current = input;
// Problem: no termination condition tied to model output
while (true) {
const result = await agent.run([{ role: "user", content: current }]);
current = result.messages.at(-1)?.content ?? "";
}
}
// Fixed: stop when the agent produces a final answer
import { AssistantAgent } from "@autogen/agents";
const agent = new AssistantAgent({
name: "support-agent",
systemMessage: "Help the user and use tools when needed.",
});
async function handleRequest(input: string) {
const result = await agent.run([{ role: "user", content: input }]);
const lastMessage = result.messages.at(-1);
if (!lastMessage) throw new Error("No assistant response returned");
// Only continue if your app explicitly expects another turn
return lastMessage.content;
}
If you’re using a group chat or orchestrator, the same bug appears when no speaker can ever terminate. The runtime keeps cycling because every agent thinks someone else should answer next.
Other Possible Causes
1) Your tool always returns something that triggers another tool call
A common loop is assistant -> tool -> assistant -> tool with no “final” message. This happens when the model sees tool output and decides it must call again.
// Example of a tool that encourages repeated calls
const searchTool = {
name: "search_policy",
description: "Search policy data",
execute: async (query: string) => {
return { status: "ok", data: query }; // too vague for termination
},
};
Fix it by returning structured, complete results and telling the model when to stop.
execute: async (query: string) => {
return {
status: "done",
answer: `Found policy match for ${query}`,
shouldContinue: false,
};
}
2) Your system prompt never defines an exit condition
If you tell the model to “keep helping until done” but never define what “done” means, it may keep trying to improve its answer forever.
const agent = new AssistantAgent({
name: "claims-agent",
systemMessage:
"Keep reasoning until you are satisfied with the answer.",
});
Use explicit termination language:
const agent = new AssistantAgent({
name: "claims-agent",
systemMessage:
"Answer once. If enough information is available, provide a final response and do not call tools again.",
});
3) You are feeding assistant output back as user input
This is easy to miss in production pipelines. If you append the assistant’s last message as a new user message, you create a self-amplifying loop.
// Bad: assistant output becomes new user input
messages.push({ role: "user", content: lastAssistantMessage });
Instead, preserve roles correctly:
messages.push({ role: "assistant", content: lastAssistantMessage });
4) Your max turn / recursion guard is too high or missing
AutoGen will usually protect you with limits like maxTurns, but if you override them incorrectly, you can let loops run long enough to look infinite in production logs.
const team = new RoundRobinGroupChat({
agents,
maxTurns: Number.MAX_SAFE_INTEGER,
});
Use sane bounds:
const team = new RoundRobinGroupChat({
agents,
maxTurns: 8,
});
How to Debug It
- •
Log every turn with role and message type
- •You want to see whether the loop is
assistant -> tool -> assistantorassistant -> user -> assistant. - •Log
role,name, and any tool invocation metadata.
- •You want to see whether the loop is
- •
Check whether any agent ever emits a terminal response
- •In AutoGen TS, inspect the final message returned by
AssistantAgent.run()or your group chat result. - •If every turn ends in a tool call, your prompt or tool contract is wrong.
- •In AutoGen TS, inspect the final message returned by
- •
Lower your turn limit temporarily
- •Set
maxTurnsto something small like3or5. - •If it still spins within that window, you’ve got a routing bug rather than just “too many turns.”
- •Set
- •
Disable tools one by one
- •Start with plain text only.
- •Re-enable each tool until the loop returns.
- •The first tool that causes repeated invocation is usually returning ambiguous output or missing completion semantics.
Prevention
- •Define explicit stop conditions in both code and prompts.
- •Keep tool outputs structured:
- •include
status - •include
answer - •include
shouldContinue
- •include
- •Put hard guards in production:
- •max turns
- •timeout
- •repeated-message detection
A good production rule is simple: if an AutoGen conversation repeats the same intent twice without new data, stop it and surface an error like AutoGenRuntimeError: conversation exceeded maxTurns instead of letting it churn indefinitely. That turns an invisible loop into an observable failure you can fix fast.
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit