[Bug Hunt][Cycle 2][Resource] Database Connection Leak in Validation Error Paths #7125

Open
opened 2026-04-10 07:59:11 +00:00 by HAL9000 · 1 comment
Owner

Metadata

  • Branch: bugfix/m3-db-connection-leak-validation-error-paths
  • Commit Message: fix(resource): ensure SQLite validation connections are closed on all code paths
  • Milestone: backlog
  • Parent Epic: #7023

Bug Report: Resource Management — Database Connection Leak in Validation Error Paths

Severity Assessment

  • Impact: Connection and file descriptor leaks during database validation failures
  • Likelihood: Medium during configuration validation with invalid database settings
  • Priority: Medium

Location

  • File: src/cleveragents/resource/handlers/database.py
  • Function: _validate_sqlite, validate_connection
  • Lines: 180-200 (_validate_sqlite)

Description

The SQLite connection validation function opens a database connection but only closes it on the success path. If an exception occurs during validation, the connection is not properly closed, leading to resource leaks during repeated validation attempts.

Evidence

def _validate_sqlite(args: dict[str, str | int | None]) -> tuple[bool, str]:
    path = str(args.get("path", ":memory:") or ":memory:")
    try:
        conn = sqlite3.connect(path)  # Connection opened
        conn.execute("SELECT 1")
        conn.close()  # Only closed on success path
        return (True, f"SQLite connection OK: {path}")
    except Exception as exc:
        return (False, f"SQLite connection failed: {exc}")  # Connection may leak

Issue: If conn.execute("SELECT 1") or any other operation throws an exception, conn.close() is never called, leaving the connection open.

Expected Behavior

Database connections should be properly closed in all code paths:

  • Success path should close connection
  • Exception path should close connection
  • Resource cleanup should be guaranteed via try/finally or context managers

Actual Behavior

  • Connections leak when validation fails due to:
    • Database file permission errors
    • Corrupted database files
    • Database locked by another process
    • Disk space issues
  • File descriptors accumulate during repeated validation attempts
  • Process file descriptor limits may be exceeded

Suggested Fix

Use proper resource management with try/finally or context manager:

def _validate_sqlite(args: dict[str, str | int | None]) -> tuple[bool, str]:
    path = str(args.get("path", ":memory:") or ":memory:")
    try:
        conn = sqlite3.connect(path)
        try:
            conn.execute("SELECT 1")
            return (True, f"SQLite connection OK: {path}")
        finally:
            conn.close()  # Always close
    except Exception as exc:
        return (False, f"SQLite connection failed: {exc}")

Or use context manager:

def _validate_sqlite(args: dict[str, str | int | None]) -> tuple[bool, str]:
    path = str(args.get("path", ":memory:") or ":memory:")
    try:
        with sqlite3.connect(path) as conn:  # Auto-close
            conn.execute("SELECT 1")
            return (True, f"SQLite connection OK: {path}")
    except Exception as exc:
        return (False, f"SQLite connection failed: {exc}")

Category

resource

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_, and @tdd_expected_fail to prove the bug exists before fixing it.

Subtasks

  • Reproduce the connection leak by triggering a validation failure (e.g., locked DB, permission error)
  • Refactor _validate_sqlite to use try/finally or a context manager to guarantee conn.close() on all paths
  • Audit validate_connection and any other validation helpers in database.py for the same pattern
  • Write BDD scenarios (Behave) covering connection cleanup on validation failure paths
  • Write Robot Framework integration test verifying no file descriptor leak under repeated failed validations
  • Run nox (all default sessions) and fix any errors
  • Verify coverage >= 97% via nox -s coverage_report

Definition of Done

  • _validate_sqlite closes the SQLite connection in all code paths (success and exception)
  • No file descriptor leak observed under repeated validation failures
  • BDD scenarios for connection cleanup on error paths pass
  • All nox stages pass
  • Coverage >= 97%

Backlog note: This issue was discovered during autonomous operation
on milestone v3.2.0. It does not block milestone completion and has been
placed in the backlog for human review and future milestone assignment.


Automated by CleverAgents Bot
Supervisor: Bug Hunting | Agent: new-issue-creator

## Metadata - **Branch**: `bugfix/m3-db-connection-leak-validation-error-paths` - **Commit Message**: `fix(resource): ensure SQLite validation connections are closed on all code paths` - **Milestone**: backlog - **Parent Epic**: #7023 ## Bug Report: Resource Management — Database Connection Leak in Validation Error Paths ### Severity Assessment - **Impact**: Connection and file descriptor leaks during database validation failures - **Likelihood**: Medium during configuration validation with invalid database settings - **Priority**: Medium ### Location - **File**: `src/cleveragents/resource/handlers/database.py` - **Function**: `_validate_sqlite`, `validate_connection` - **Lines**: 180-200 (_validate_sqlite) ### Description The SQLite connection validation function opens a database connection but only closes it on the success path. If an exception occurs during validation, the connection is not properly closed, leading to resource leaks during repeated validation attempts. ### Evidence ```python def _validate_sqlite(args: dict[str, str | int | None]) -> tuple[bool, str]: path = str(args.get("path", ":memory:") or ":memory:") try: conn = sqlite3.connect(path) # Connection opened conn.execute("SELECT 1") conn.close() # Only closed on success path return (True, f"SQLite connection OK: {path}") except Exception as exc: return (False, f"SQLite connection failed: {exc}") # Connection may leak ``` **Issue**: If `conn.execute("SELECT 1")` or any other operation throws an exception, `conn.close()` is never called, leaving the connection open. ### Expected Behavior Database connections should be properly closed in all code paths: - Success path should close connection - Exception path should close connection - Resource cleanup should be guaranteed via try/finally or context managers ### Actual Behavior - Connections leak when validation fails due to: - Database file permission errors - Corrupted database files - Database locked by another process - Disk space issues - File descriptors accumulate during repeated validation attempts - Process file descriptor limits may be exceeded ### Suggested Fix Use proper resource management with try/finally or context manager: ```python def _validate_sqlite(args: dict[str, str | int | None]) -> tuple[bool, str]: path = str(args.get("path", ":memory:") or ":memory:") try: conn = sqlite3.connect(path) try: conn.execute("SELECT 1") return (True, f"SQLite connection OK: {path}") finally: conn.close() # Always close except Exception as exc: return (False, f"SQLite connection failed: {exc}") ``` Or use context manager: ```python def _validate_sqlite(args: dict[str, str | int | None]) -> tuple[bool, str]: path = str(args.get("path", ":memory:") or ":memory:") try: with sqlite3.connect(path) as conn: # Auto-close conn.execute("SELECT 1") return (True, f"SQLite connection OK: {path}") except Exception as exc: return (False, f"SQLite connection failed: {exc}") ``` ### Category resource ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it. ## Subtasks - [ ] Reproduce the connection leak by triggering a validation failure (e.g., locked DB, permission error) - [ ] Refactor `_validate_sqlite` to use `try/finally` or a context manager to guarantee `conn.close()` on all paths - [ ] Audit `validate_connection` and any other validation helpers in `database.py` for the same pattern - [ ] Write BDD scenarios (Behave) covering connection cleanup on validation failure paths - [ ] Write Robot Framework integration test verifying no file descriptor leak under repeated failed validations - [ ] Run `nox` (all default sessions) and fix any errors - [ ] Verify coverage >= 97% via `nox -s coverage_report` ## Definition of Done - [ ] `_validate_sqlite` closes the SQLite connection in all code paths (success and exception) - [ ] No file descriptor leak observed under repeated validation failures - [ ] BDD scenarios for connection cleanup on error paths pass - [ ] All nox stages pass - [ ] Coverage >= 97% > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.2.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: new-issue-creator
Author
Owner

Verified — Critical resource bug: database connection leak in validation error paths. MoSCoW: Must-have. Priority: Critical.


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

✅ **Verified** — Critical resource bug: database connection leak in validation error paths. MoSCoW: Must-have. Priority: Critical. --- **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#7125
No description provided.