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

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

When CrewAI starts repeating the same task over and over during a scaled run, you usually end up with agent infinite loop when scaling. In practice, this means the agent keeps re-entering execution because it never reaches a clean terminal state, or it keeps getting re-scheduled by your orchestration code.

This shows up most often when you add more workers, more tasks, or a retry wrapper around Crew execution in TypeScript. The error is usually not “CrewAI is broken” — it’s a control-flow problem in your agent setup.

The Most Common Cause

The #1 cause is an agent that never has a valid stopping condition. In CrewAI terms, that usually means the Agent keeps producing intermediate steps because the task description is vague, the tool loop never resolves, or your code re-invokes kickoff() on failure without a hard stop.

Here’s the broken pattern I see most often in TypeScript:

BrokenFixed
Agent can keep reasoning foreverAgent has bounded output and clear completion criteria
Retry wrapper blindly re-calls kickoffRetry wrapper limits attempts and fails fast
Task description is open-endedTask asks for one concrete deliverable
// ❌ Broken: no clear stopping condition + unbounded retry loop
import { Agent, Crew, Task } from "@crewai/typescript";

const analyst = new Agent({
  role: "Claims Analyst",
  goal: "Analyze claims data",
  backstory: "You are precise and thorough.",
  tools: [claimsSearchTool],
});

const task = new Task({
  description: "Investigate this claim and keep refining until it's perfect.",
  expectedOutput: "A useful analysis.",
  agent: analyst,
});

const crew = new Crew({
  agents: [analyst],
  tasks: [task],
});

async function run() {
  let result;
  while (true) {
    result = await crew.kickoff();
    if (result) break;
  }
}
// ✅ Fixed: bounded task + explicit output + limited retries
import { Agent, Crew, Task } from "@crewai/typescript";

const analyst = new Agent({
  role: "Claims Analyst",
  goal: "Produce a final claim assessment in one pass",
  backstory: "You write concise operational summaries.",
  tools: [claimsSearchTool],
});

const task = new Task({
  description:
    "Review claim #1234 and return exactly one JSON object with fields: status, summary, evidence, nextAction.",
  expectedOutput:
    "Valid JSON with status, summary, evidence, nextAction. No extra text.",
  agent: analyst,
});

const crew = new Crew({
  agents: [analyst],
  tasks: [task],
});

async function run() {
  const maxAttempts = 2;

  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    const result = await crew.kickoff();
    if (result) return result;
  }

  throw new Error("CrewAI kickoff failed after maxAttempts=2");
}

If you only fix one thing, fix this. A lot of “infinite loop when scaling” incidents are really “my orchestration code made every failure retriable forever.”

Other Possible Causes

1) Tool calls that never terminate

If a tool returns partial data and the agent thinks it should call again, you get repeated tool usage. This is common with search tools that always return “more results available”.

// Bad tool behavior
const searchTool = async (query: string) => {
  return {
    results: [],
    nextCursor: "always-present-cursor",
    message: "More data available",
  };
};

Fix it by making the tool return a terminal response when there’s nothing else to fetch.

// Better tool behavior
const searchTool = async (query: string) => {
  const results = await db.search(query);

  return {
    results,
    nextCursor: results.length ? null : null,
    done: true,
  };
};

2) Multiple agents waiting on each other

In scaled crews, one agent may produce output another agent expects before either can finish. That creates a deadlock-like loop at the orchestration level.

// Agent A expects Agent B to finalize first
const writerTask = new Task({
  description: "Write the report after reviewer approval.",
});

const reviewerTask = new Task({
  description: "Review only after writer produces final report.",
});

Break circular dependencies. One agent should own completion.

3) Misconfigured iteration limits

If your CrewAI TypeScript config exposes maxIterations, maxRetries, or similar controls and they’re too high or unset, scaling turns small loops into long-running failures.

const crew = new Crew({
  agents,
  tasks,
  maxIterations: Infinity as unknown as number,
});

Use explicit caps.

const crew = new Crew({
  agents,
  tasks,
  maxIterations: 5,
});

4) Non-deterministic shared state between workers

When multiple runs share mutable memory, one worker can keep re-triggering another worker’s task. This shows up when you reuse the same in-memory store across concurrent crews.

// Risky shared state
const memoryStore = new Map();

function createCrew() {
   return new Crew({ agents, tasks, memoryStore });
}

Use per-run state or isolate by request ID.

How to Debug It

  1. Turn on verbose logs

    • Look for repeated Agent.execute, Task.run, or tool invocation lines.
    • If you see the same prompt/tool pair looping, it’s not scaling — it’s recurrence.
  2. Inspect the last successful step

    • Check whether the agent ever emitted a final answer.
    • If logs end with intermediate reasoning or repeated tool calls, your task lacks termination.
  3. Disable retries temporarily

    • Remove wrapper loops around crew.kickoff().
    • If the issue disappears, your app code is causing the infinite loop.
  4. Reduce to one agent and one task

    • Run the exact same prompt with no parallelism.
    • If single-agent works but multi-agent fails, you likely have circular dependencies or shared-state contamination.

Prevention

  • Write tasks with one clear terminal output:
    • “Return JSON”
    • “Return a decision”
    • “Return top-3 findings”
  • Put hard caps on execution:
const crew = new Crew({ agents, tasks, maxIterations: 5 });
  • Never wrap kickoff() in an unbounded while (true) or recursive retry without a max attempt count.
  • Keep tools deterministic:
    • Return done, nextCursor, or hasMore
    • Avoid ambiguous responses like “continue exploring”

If you’re seeing agent infinite loop when scaling in CrewAI TypeScript, start with termination conditions first. In most cases, once you make outputs explicit and cap retries/iterations, the loop disappears immediately.


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