How to Fix 'duplicate tool calls' in CrewAI (Python)

By Cyprian AaronsUpdated 2026-04-21
duplicate-tool-callscrewaipython

What the error means

duplicate tool calls in CrewAI usually means the same tool invocation is being triggered more than once for a single agent step. In practice, this shows up when you combine overlapping agent instructions, repeated task execution, or a loop that replays the same message history.

The error often appears when an agent with tools is asked to reason, then gets re-run with the same context and tool state. You’ll typically see it around Agent, Task, Crew, or tool adapters like BaseTool.

The Most Common Cause

The #1 cause is reusing the same agent/task flow in a way that causes the model to emit the same tool call twice. This usually happens when you manually invoke an agent loop, then also let Crew.kickoff() run the same task again.

Here’s the broken pattern:

from crewai import Agent, Task, Crew
from crewai_tools import SerperDevTool

search_tool = SerperDevTool()

researcher = Agent(
    role="Researcher",
    goal="Find current information",
    backstory="You research facts from the web.",
    tools=[search_tool],
    verbose=True,
)

task = Task(
    description="Search for CrewAI duplicate tool calls error causes.",
    expected_output="A short summary.",
    agent=researcher,
)

crew = Crew(
    agents=[researcher],
    tasks=[task],
    verbose=True,
)

# Broken: running the same workflow twice can replay tool calls
result_1 = crew.kickoff()
result_2 = crew.kickoff()

And here’s the fixed version:

from crewai import Agent, Task, Crew
from crewai_tools import SerperDevTool

search_tool = SerperDevTool()

researcher = Agent(
    role="Researcher",
    goal="Find current information",
    backstory="You research facts from the web.",
    tools=[search_tool],
    verbose=True,
)

task = Task(
    description="Search for CrewAI duplicate tool calls error causes.",
    expected_output="A short summary.",
    agent=researcher,
)

crew = Crew(
    agents=[researcher],
    tasks=[task],
    verbose=True,
)

# Fixed: kickoff once per fresh run
result = crew.kickoff()

If you need multiple runs, create a new Crew instance or reset your orchestration layer between runs. Don’t reuse a live conversation state unless you know exactly how tool messages are being stored.

Other Possible Causes

1. Duplicate tools attached to the same agent

If you add the same tool twice, some models will emit identical calls and CrewAI may surface it as a duplicate execution problem.

# Broken
agent = Agent(
    role="Analyst",
    goal="Analyze data",
    backstory="You work with internal data.",
    tools=[search_tool, search_tool],  # duplicated
)
# Fixed
agent = Agent(
    role="Analyst",
    goal="Analyze data",
    backstory="You work with internal data.",
    tools=[search_tool],
)

2. Tool wrapper calling itself recursively

This happens when a custom tool implementation calls back into another agent/tool path that triggers the same tool again.

from crewai_tools import BaseTool

class MyTool(BaseTool):
    name: str = "my_tool"
    description: str = "Custom tool"

    def _run(self, query: str) -> str:
        # Broken: indirect recursion through another call path
        return self._run(query)

Fix it by making _run() strictly one-pass:

class MyTool(BaseTool):
    name: str = "my_tool"
    description: str = "Custom tool"

    def _run(self, query: str) -> str:
        return f"Processed: {query}"

3. Replaying chat history with old tool messages

If you persist memory or message history and feed it back unchanged, CrewAI can see prior tool_call_id entries and attempt to resolve them again.

# Broken idea: reusing old messages directly
messages = load_messages_from_db()
crew.kickoff(inputs={"messages": messages})

Instead, pass clean inputs and let CrewAI reconstruct execution state:

inputs = {"topic": "duplicate tool calls in CrewAI"}
crew.kickoff(inputs=inputs)

4. Overlapping delegation between agents

If two agents can both use the same tool and one delegates back to the other, you can get repeated execution on the same prompt.

# Broken pattern: both agents share same external search tool and delegate freely
researcher.tools = [search_tool]
analyst.tools = [search_tool]

A safer setup is to separate responsibilities:

researcher.tools = [search_tool]
analyst.tools = []

How to Debug It

  1. Turn on verbose logging

    • Set verbose=True on Agent and Crew.
    • Look for repeated lines like:
      • Calling tool ...
      • Executing tool ...
      • duplicate tool calls
    • If you see the same call twice with identical arguments, you’ve found your loop.
  2. Check whether kickoff is being called more than once

    • Search your code for multiple crew.kickoff() invocations.
    • Watch for retries in FastAPI endpoints, Celery jobs, or background workers.
    • A common bug is calling kickoff in both request handling and post-processing.
  3. Inspect your tools list

    • Print each agent’s tools before running:
      print([tool.name for tool in researcher.tools])
      
    • Make sure there are no duplicates.
    • Also confirm you’re not creating two instances of the same wrapper around one API client.
  4. Disable memory/history temporarily

    • Run one task with fresh inputs only.
    • If the error disappears, your message replay layer is likely reintroducing old tool calls.
    • Re-enable memory only after verifying that stored messages do not include stale tool_call_id records.

Prevention

  • Keep each agent’s tool list minimal.

    • One agent should own one responsibility.
    • Don’t give every agent access to every external API.
  • Treat each Crew.kickoff() as a single execution unit.

    • If you need reruns, build a new crew instance or reset state explicitly.
  • Don’t persist raw assistant/tool messages unless you understand how CrewAI resolves them.

    • Store business output separately from execution traces.
  • Add tests for repeated runs.

    • Run the same workflow twice in CI and assert that it doesn’t emit duplicate tool invocations or crash on replay.

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