Skip to content

[Bug] Team cancel does not cascade to currently-running member agents #7730

@yeyan00

Description

@yeyan00

Description

When a team run is cancelled via cancel_run(team_run_id), only the team-level execution is interrupted. Member agents that are currently running continue to completion because they generate their own run_id via uuid4() — the team's cancelled_runs entry does not match the member's run_id, so raise_if_cancelled() inside the member agent never detects the cancellation.

This wastes tokens, time, and compute resources on member runs that the user already intended to stop.

Steps to Reproduce

When a team run is cancelled via cancel_run(team_run_id), only the team-level execution is interrupted. Member agents that are currently running continue to completion because they generate their own run_id via uuid4() — the team's cancelled_runs entry does not match the member's run_id, so raise_if_cancelled() inside the member agent never detects the cancellation.

This wastes tokens, time, and compute resources on member runs that the user already intended to stop.

Reproduction Script

import threading, time
from agno.agent import Agent
from agno.team import Team
from agno.models.openai import OpenAIChat
from agno.db.sqlite import SqliteDb

db = SqliteDb(db_file="tmp/repro.db")
model = OpenAIChat(id="<model-id>")

slow_agent = Agent(
    name="SlowAgent",
    model=model,
    instructions="Write at least 10 paragraphs. Be extremely verbose.",
    db=db,
)

team = Team(
    name="TestTeam",
    members=[slow_agent],
    model=model,
    instructions="Delegate the task to SlowAgent.",
    db=db,
)

run_id = "repro-team-cancel-001"
result = {}

def run_team():
    try:
        result["response"] = team.run(
            input="Write a very detailed 10-paragraph essay about AI history.",
            session_id="repro-session",
            run_id=run_id,
            stream=False,
        )
    except Exception as e:
        result["error"] = e

t = threading.Thread(target=run_team)
t.start()

# Wait for team to delegate to member, then cancel
time.sleep(8)
team.cancel_run(run_id)

t.join(timeout=120)

Agent Configuration (if applicable)

No response

Expected Behavior

  • Team run status: CANCELLED
  • Member agent run status: CANCELLED (should stop at next checkpoint when team is cancelled)

Actual Behavior

Total runs in session: 2
  Run[0]: type=RunOutput,     status=COMPLETED, content_len=12498, run_id=54e914cc-...
  Run[1]: type=TeamRunOutput, status=CANCELLED, content_len=35,    run_id=repro-team-cancel-001

BUG: Member completed (status=COMPLETED, content_len=12498) despite team cancel!

The member generated a full 12,498-character essay after the team was already cancelled. The member's run_id (54e914cc-...) is different from the team's run_id (repro-team-cancel-001), so raise_if_cancelled() never detects the cancellation.

Root Cause

cancel_run("team-run-id")
  → _cancelled_runs["team-run-id"] = True

member agent inside run()
  → generates own run_id = "member-run-id" (via uuid4())
  → raise_if_cancelled("member-run-id")
  → checks _cancelled_runs["member-run-id"] → False (key doesn't exist!)
  → continues running...

The team's cancellation and the member's cancellation are completely decoupled. The member has no way to know its parent team was cancelled.

Screenshots or Logs (if applicable)

No response

Environment

- Agno version: 2.6.3
- Python: 3.10+
- OS: Windows

Possible Solutions (optional)

No response

Additional Context

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions