Resource Leak in Agent class due to not cancelling running tasks on dispose #9082

Open
opened 2026-04-14 07:19:19 +00:00 by HAL9000 · 2 comments
Owner

Metadata

  • Commit Message: fix(agents): cancel running asyncio tasks in Agent.dispose to prevent resource leak
  • Branch: fix/agent-dispose-cancel-tasks

Background and Context

A resource leak has been identified in the Agent class in src/cleveragents/agents/base.py.

The dispose method in the Agent class does not cancel the running asyncio tasks that are stored in the _tasks list. If the agent is disposed of while there are still running tasks, these tasks will continue to run in the background, consuming resources and potentially leading to unexpected behavior.

Code Evidence:

  • cleveragents.agents.base.Agent.dispose (line 86 at time of discovery): The dispose method does not cancel tasks in self._tasks.

Environment Verification:
This issue is reproducible in the actual project context. Create an agent, send it a message that results in a long-running task, and then call dispose. The task will continue to run in the background.

Actionability:
The fix is to iterate over the _tasks list in the dispose method and cancel each task before disposing of the streams:

def dispose(self) -> None:
    for task in self._tasks:
        task.cancel()
    if hasattr(self.input_stream, "dispose"):
        self.input_stream.dispose()
    if hasattr(self.output_stream, "dispose"):
        self.output_stream.dispose()

Expected Behavior

When Agent.dispose() is called, all running asyncio tasks stored in self._tasks are cancelled before the input and output streams are disposed. No background tasks continue running after disposal.

Acceptance Criteria

  • Agent.dispose() iterates over self._tasks and calls .cancel() on each task before disposing streams
  • Cancelled tasks do not raise unhandled exceptions after disposal
  • Disposing an agent with no running tasks continues to work correctly (no regression)
  • Disposing an agent with one or more running tasks cancels all of them
  • BDD scenario added: agent with a long-running task is disposed; task is confirmed cancelled

Subtasks

  • Update Agent.dispose() in src/cleveragents/agents/base.py to cancel all tasks in self._tasks
  • Tests (Behave): Add BDD scenario for Agent.dispose() cancelling running tasks
  • Tests (Behave): Add BDD scenario for Agent.dispose() with no running tasks (regression guard)
  • Tests (Robot): Add integration test verifying no background tasks survive after disposal
  • Verify coverage >= 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly (fix(agents): cancel running asyncio tasks in Agent.dispose to prevent resource leak), followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly (fix/agent-dispose-cancel-tasks).
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.

Automated by CleverAgents Bot
Agent: new-issue-creator

## Metadata - **Commit Message**: `fix(agents): cancel running asyncio tasks in Agent.dispose to prevent resource leak` - **Branch**: `fix/agent-dispose-cancel-tasks` ## Background and Context A resource leak has been identified in the `Agent` class in `src/cleveragents/agents/base.py`. The `dispose` method in the `Agent` class does not cancel the running asyncio tasks that are stored in the `_tasks` list. If the agent is disposed of while there are still running tasks, these tasks will continue to run in the background, consuming resources and potentially leading to unexpected behavior. **Code Evidence:** - `cleveragents.agents.base.Agent.dispose` (line 86 at time of discovery): The `dispose` method does not cancel tasks in `self._tasks`. **Environment Verification:** This issue is reproducible in the actual project context. Create an agent, send it a message that results in a long-running task, and then call `dispose`. The task will continue to run in the background. **Actionability:** The fix is to iterate over the `_tasks` list in the `dispose` method and cancel each task before disposing of the streams: ```python def dispose(self) -> None: for task in self._tasks: task.cancel() if hasattr(self.input_stream, "dispose"): self.input_stream.dispose() if hasattr(self.output_stream, "dispose"): self.output_stream.dispose() ``` ## Expected Behavior When `Agent.dispose()` is called, all running asyncio tasks stored in `self._tasks` are cancelled before the input and output streams are disposed. No background tasks continue running after disposal. ## Acceptance Criteria - [ ] `Agent.dispose()` iterates over `self._tasks` and calls `.cancel()` on each task before disposing streams - [ ] Cancelled tasks do not raise unhandled exceptions after disposal - [ ] Disposing an agent with no running tasks continues to work correctly (no regression) - [ ] Disposing an agent with one or more running tasks cancels all of them - [ ] BDD scenario added: agent with a long-running task is disposed; task is confirmed cancelled ## Subtasks - [ ] Update `Agent.dispose()` in `src/cleveragents/agents/base.py` to cancel all tasks in `self._tasks` - [ ] Tests (Behave): Add BDD scenario for `Agent.dispose()` cancelling running tasks - [ ] Tests (Behave): Add BDD scenario for `Agent.dispose()` with no running tasks (regression guard) - [ ] Tests (Robot): Add integration test verifying no background tasks survive after disposal - [ ] Verify coverage >= 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly (`fix(agents): cancel running asyncio tasks in Agent.dispose to prevent resource leak`), followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly (`fix/agent-dispose-cancel-tasks`). - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. --- **Automated by CleverAgents Bot** Agent: new-issue-creator
HAL9000 added this to the v3.5.0 milestone 2026-04-14 07:37:28 +00:00
Author
Owner

🔍 Triage Decision — [AUTO-OWNR-2]

Status: VERIFIED

MoSCoW: Must have
Priority: High
Milestone: v3.5.0

Reasoning: Failing to cancel running tasks on Agent dispose causes resource leaks that degrade reliability in long-running deployments. This is a correctness issue in the core Agent class that must be addressed.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

## 🔍 Triage Decision — [AUTO-OWNR-2] **Status:** ✅ VERIFIED **MoSCoW:** Must have **Priority:** High **Milestone:** v3.5.0 **Reasoning:** Failing to cancel running tasks on Agent dispose causes resource leaks that degrade reliability in long-running deployments. This is a correctness issue in the core Agent class that must be addressed. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Triage: Verified [AUTO-OWNR-1]

Valid bug: Agent class has a resource leak — running tasks are not cancelled on dispose. This causes resource leaks in long-running sessions.

Assigning to v3.5.0 (Autonomy Hardening) as this affects long-running autonomous execution. Priority High — resource leak causes failures in production.

MoSCoW: Must Have — proper resource cleanup is essential for reliable autonomous operation.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Triage: Verified** [AUTO-OWNR-1] Valid bug: `Agent` class has a resource leak — running tasks are not cancelled on dispose. This causes resource leaks in long-running sessions. Assigning to **v3.5.0** (Autonomy Hardening) as this affects long-running autonomous execution. Priority **High** — resource leak causes failures in production. MoSCoW: **Must Have** — proper resource cleanup is essential for reliable autonomous operation. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#9082
No description provided.