How to Fix 'agent infinite loop when scaling' in AutoGen (TypeScript)

By Cyprian AaronsUpdated 2026-04-21
agent-infinite-loop-when-scalingautogentypescript

When AutoGen starts re-entering the same agent flow over and over, you usually have a termination bug, not a scaling bug. In TypeScript, this shows up most often when you add more workers, more messages, or a longer-running orchestrator and the conversation never hits a hard stop.

The common symptom is some variation of:

  • Error: agent infinite loop detected
  • Max turns exceeded
  • A chat that keeps calling the same AssistantAgent or GroupChatManager path until your process stalls

The Most Common Cause

The #1 cause is missing or ineffective termination logic. In AutoGen TypeScript, people often wire up an AssistantAgent to respond to every message, but they forget to define a stop condition that actually matches the model’s output.

Here’s the broken pattern versus the fixed one.

BrokenFixed
No termination checkExplicit termination function
Agent always repliesAgent stops on sentinel text
Infinite back-and-forth in group chatControlled max turns + stop condition
// ❌ Broken: no real stop condition
import { AssistantAgent, UserProxyAgent } from "@autogen/core";

const assistant = new AssistantAgent({
  name: "assistant",
  systemMessage: "You are a helpful banking assistant.",
});

const user = new UserProxyAgent({
  name: "user",
});

await user.send({
  recipient: assistant,
  message: "Summarize this loan application and keep going until done.",
});
// ✅ Fixed: explicit termination condition
import { AssistantAgent, UserProxyAgent } from "@autogen/core";

const assistant = new AssistantAgent({
  name: "assistant",
  systemMessage:
    "You are a helpful banking assistant. End every final answer with 'TERMINATE'.",
});

const user = new UserProxyAgent({
  name: "user",
});

const response = await user.send({
  recipient: assistant,
  message: "Summarize this loan application.",
});

// Example guard at the orchestration layer
if (typeof response.content === "string" && response.content.includes("TERMINATE")) {
  console.log("Conversation complete");
}

If you’re using GroupChatManager, the same rule applies: every agent loop needs a deterministic exit. Don’t rely on “the model will know when to stop.”

Other Possible Causes

1) Your speaker selection keeps picking the same agent

In multi-agent setups, AutoGen can keep selecting the same AssistantAgent if your selector logic is too permissive.

// Bad selector: always returns the first agent
const selectSpeaker = () => agents[0];
// Better: rotate speakers and exclude last speaker
const selectSpeaker = (agents: string[], lastSpeaker?: string) =>
  agents.find((a) => a !== lastSpeaker) ?? agents[0];

If you use custom routing, make sure it cannot return the same speaker forever.

2) Tool calls are returning empty or non-terminal outputs

A tool that returns {} or "ok" without advancing state can cause the assistant to ask again.

// Problematic tool result
return { status: "ok" };
// Better tool result includes state transition data
return {
  status: "done",
  nextAction: "terminate",
  accountId,
};

If your agent depends on tool output to decide whether to continue, return something explicit.

3) Your max turns is too high or not enforced

Some teams configure retries and turns in multiple places and assume one of them will stop execution. In practice, only one guard matters if it’s actually enforced.

const config = {
  maxTurns: 1000,
  maxRetries: 5,
};

Use something bounded and realistic:

const config = {
  maxTurns: 12,
  maxRetries: 2,
};

If you are processing structured tasks like claims triage or KYC review, low double digits is usually enough.

4) The prompt encourages endless continuation

Prompts like “keep refining until perfect” or “continue until all edge cases are covered” are loop fuel.

// Risky prompt
systemMessage:
  "Keep improving the answer until there are no more possible improvements.";
// Safer prompt
systemMessage:
  "Provide one final answer. If complete, end with TERMINATE.";

Model behavior follows instructions. If you ask for infinite refinement, don’t be surprised when AutoGen never settles.

How to Debug It

  1. Log every turn with speaker name and message content
    You want to see which agent repeats first. If AssistantAgent answers itself three times in a row, your routing is wrong.

  2. Check for a real termination token
    Search for TERMINATE, DONE, or whatever sentinel you expect. If your code checks for "done" but your prompt says "complete", that’s your bug.

  3. Temporarily cap turns at a low number
    Set maxTurns to 3 or 5. If the loop still happens immediately, it’s not scaling; it’s logic.

  4. Disable tools and custom selectors one by one
    Start with plain agent-to-agent messaging. Then re-enable tools, then selection logic, then retries. The component that reintroduces repetition is usually the culprit.

Prevention

  • Always define a termination contract in both places:
    • prompt instruction
    • orchestration code
  • Keep routing deterministic:
    • avoid “pick any agent” logic without exclusions
  • Add observability early:
    • log turn count
    • log selected speaker
    • log final stop reason

If you’re building production workflows in AutoGen TypeScript, treat infinite loops as an orchestration defect, not an LLM mystery. Once you add explicit termination, bounded turns, and predictable speaker selection, this error usually disappears fast.


Keep learning

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

Related Guides