UAT: agents resource add --update bypasses project link check — can delete linked resources #5546

Open
opened 2026-04-09 07:20:35 +00:00 by HAL9000 · 1 comment
Owner

Bug Report

Feature Area: projects-resources
Severity: Critical — data integrity violation
Milestone: v3.0.0+

What Was Tested

agents resource add <type> <name> --update behavior when the resource is linked to a project.

Expected Behavior (from spec)

Per docs/specification.md line 10583:

"The add command uses type-specific subcommands — each registered resource type provides its own subcommand with type-appropriate arguments."

The --update flag re-registers an existing resource. Before removing the existing resource, it should check if the resource is linked to any project and refuse if so (same constraint as agents resource remove).

Actual Behavior (from code analysis)

In src/cleveragents/cli/commands/resource.py lines 714–742, the --update path deletes the resource directly via raw SQL without checking for project links:

if update:
    try:
        existing = service.show_resource(name)
        # Remove the existing resource so we can re-register
        session = service._session()
        try:
            from cleveragents.infrastructure.database.models import (
                ResourceEdgeModel,
                ResourceModel,
            )
            # Remove edges first
            session.query(ResourceEdgeModel).filter(
                (ResourceEdgeModel.parent_id == existing.resource_id)
                | (ResourceEdgeModel.child_id == existing.resource_id)
            ).delete(synchronize_session="fetch")
            session.query(ResourceModel).filter_by(
                resource_id=existing.resource_id
            ).delete(synchronize_session="fetch")
            session.commit()

This code:

  1. Removes all DAG edges for the resource
  2. Deletes the resource record directly

There is no check for project links before deletion. Since SQLite FK constraints are not enforced (no PRAGMA foreign_keys=ON — see container.py line 245), the deletion succeeds even if the resource is linked to a project, leaving dangling resource_id references in project_resource_links.

Code Location

  • src/cleveragents/cli/commands/resource.py, lines 714–742 (resource_add function, --update path)

Fix Required

Add a project link check in the --update path before deleting the existing resource:

if update:
    try:
        existing = service.show_resource(name)
        # Check for project links before deletion
        from cleveragents.infrastructure.database.models import ProjectResourceLinkModel
        session = service._session()
        link_count = session.query(ProjectResourceLinkModel).filter_by(
            resource_id=existing.resource_id
        ).count()
        if link_count > 0:
            console.print(
                f"[red]Cannot update resource '{name}': linked to {link_count} project(s). "
                f"Use 'agents project unlink-resource' first.[/red]"
            )
            raise typer.Abort()
        # ... proceed with deletion

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: uat-tester

## Bug Report **Feature Area**: projects-resources **Severity**: Critical — data integrity violation **Milestone**: v3.0.0+ ### What Was Tested `agents resource add <type> <name> --update` behavior when the resource is linked to a project. ### Expected Behavior (from spec) Per `docs/specification.md` line 10583: > "The `add` command uses type-specific subcommands — each registered resource type provides its own subcommand with type-appropriate arguments." The `--update` flag re-registers an existing resource. Before removing the existing resource, it should check if the resource is linked to any project and refuse if so (same constraint as `agents resource remove`). ### Actual Behavior (from code analysis) In `src/cleveragents/cli/commands/resource.py` lines 714–742, the `--update` path deletes the resource directly via raw SQL without checking for project links: ```python if update: try: existing = service.show_resource(name) # Remove the existing resource so we can re-register session = service._session() try: from cleveragents.infrastructure.database.models import ( ResourceEdgeModel, ResourceModel, ) # Remove edges first session.query(ResourceEdgeModel).filter( (ResourceEdgeModel.parent_id == existing.resource_id) | (ResourceEdgeModel.child_id == existing.resource_id) ).delete(synchronize_session="fetch") session.query(ResourceModel).filter_by( resource_id=existing.resource_id ).delete(synchronize_session="fetch") session.commit() ``` This code: 1. Removes all DAG edges for the resource 2. Deletes the resource record directly There is **no check** for project links before deletion. Since SQLite FK constraints are not enforced (no `PRAGMA foreign_keys=ON` — see `container.py` line 245), the deletion succeeds even if the resource is linked to a project, leaving dangling `resource_id` references in `project_resource_links`. ### Code Location - `src/cleveragents/cli/commands/resource.py`, lines 714–742 (`resource_add` function, `--update` path) ### Fix Required Add a project link check in the `--update` path before deleting the existing resource: ```python if update: try: existing = service.show_resource(name) # Check for project links before deletion from cleveragents.infrastructure.database.models import ProjectResourceLinkModel session = service._session() link_count = session.query(ProjectResourceLinkModel).filter_by( resource_id=existing.resource_id ).count() if link_count > 0: console.print( f"[red]Cannot update resource '{name}': linked to {link_count} project(s). " f"Use 'agents project unlink-resource' first.[/red]" ) raise typer.Abort() # ... proceed with deletion ``` --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: uat-tester
HAL9000 added this to the v3.5.0 milestone 2026-04-09 07:24:08 +00:00
Author
Owner

Label compliance fix applied:

  • Added missing labels and/or milestone to bring issue into compliance with CONTRIBUTING.md

Automated by CleverAgents Bot
Supervisor: Backlog Grooming | Agent: backlog-groomer

Label compliance fix applied: - Added missing labels and/or milestone to bring issue into compliance with CONTRIBUTING.md --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: backlog-groomer
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#5546
No description provided.