UAT: agents actor add bypasses duplicate detection — silently upserts instead of failing without --update #3481

Closed
opened 2026-04-05 18:32:25 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/actor-add-duplicate-detection
  • Commit Message: fix(actor-cli): enforce duplicate detection in actor add command
  • Milestone: (Backlog — no milestone assigned)
  • Parent Epic: #392

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.

Background and Context

The agents actor add CLI command is supposed to fail with an error when an actor with the same name already exists and --update is not provided. The spec defines this behavior explicitly:

╭─ Error ─────────────────────────────────────────────────╮
│ Actor already exists: local/reviewer                    │
│ Registered: 2026-02-07 14:22                            │
│ Use --update to replace the existing actor definition.  │
╰─────────────────────────────────────────────────────────╯
✗ ERROR Actor already registered — use --update to replace

Current Behavior (Bug)

The CLI add command in src/cleveragents/cli/commands/actor.py calls registry.upsert_actor() (the legacy upsert path) regardless of whether --update was passed. The update_existing flag is only used to change the display title ("Actor added" vs "Actor updated"), but it does NOT prevent the upsert from happening.

The ActorRegistry.add() method (the YAML-first path) does implement duplicate detection correctly:

if not update:
    try:
        self._actor_service.get_actor(name)
        raise ValidationError(
            f"Actor '{name}' already exists. Pass update=True to overwrite."
        )
    except Exception as exc:
        if "already exists" in str(exc):
            raise

But the CLI bypasses this by calling registry.upsert_actor() directly instead of registry.add().

Steps to Reproduce

  1. Register an actor: agents actor add --config ./actors/my-actor.yaml
  2. Run the same command again without --update: agents actor add --config ./actors/my-actor.yaml
  3. Expected: Command fails with error panel "Actor already exists: ..."
  4. Actual: Command silently succeeds, updating the existing actor

Expected Behavior

When --update is not provided and actor already exists:

  • Exit code: 1
  • Display error panel with actor name, registration date, and hint to use --update
  • Print ✗ ERROR Actor already registered — use --update to replace

Code Location

  • src/cleveragents/cli/commands/actor.py, add() function (lines ~563–597)
  • The fix is to either:
    a. Call registry.add(yaml_text, update=update_existing) instead of registry.upsert_actor()
    b. Or add a pre-check: if not update_existing, check if actor exists and fail with the spec-required error panel

Subtasks

  • Investigate add() in src/cleveragents/cli/commands/actor.py and confirm the upsert bypass
  • Fix CLI add() to call registry.add(yaml_text, update=update_existing) or add a pre-existence check
  • Render the spec-required Rich error panel when duplicate is detected without --update
  • Ensure exit code 1 is returned on duplicate detection
  • Tests (Behave): Add scenario — agents actor add without --update on existing actor fails with error panel
  • Tests (Behave): Add scenario — agents actor add --update on existing actor succeeds
  • Tests (Robot): Add integration test for duplicate detection in actor add
  • Verify coverage >= 97% via nox -e coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

  • All subtasks above are completed and checked off
  • agents actor add (without --update) on an existing actor exits with code 1 and displays the spec-required error panel
  • agents actor add --update on an existing actor succeeds as before
  • A Git commit is created where the first line matches the Commit Message in Metadata exactly, with ISSUES CLOSED: #<N> in the footer
  • The commit is pushed to the branch matching the Branch in Metadata exactly
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done
  • All nox stages pass
  • Coverage >= 97%

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/actor-add-duplicate-detection` - **Commit Message**: `fix(actor-cli): enforce duplicate detection in actor add command` - **Milestone**: (Backlog — no milestone assigned) - **Parent Epic**: #392 > **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. ## Background and Context The `agents actor add` CLI command is supposed to fail with an error when an actor with the same name already exists and `--update` is not provided. The spec defines this behavior explicitly: ``` ╭─ Error ─────────────────────────────────────────────────╮ │ Actor already exists: local/reviewer │ │ Registered: 2026-02-07 14:22 │ │ Use --update to replace the existing actor definition. │ ╰─────────────────────────────────────────────────────────╯ ✗ ERROR Actor already registered — use --update to replace ``` ## Current Behavior (Bug) The CLI `add` command in `src/cleveragents/cli/commands/actor.py` calls `registry.upsert_actor()` (the legacy upsert path) regardless of whether `--update` was passed. The `update_existing` flag is only used to change the display title ("Actor added" vs "Actor updated"), but it does NOT prevent the upsert from happening. The `ActorRegistry.add()` method (the YAML-first path) does implement duplicate detection correctly: ```python if not update: try: self._actor_service.get_actor(name) raise ValidationError( f"Actor '{name}' already exists. Pass update=True to overwrite." ) except Exception as exc: if "already exists" in str(exc): raise ``` But the CLI bypasses this by calling `registry.upsert_actor()` directly instead of `registry.add()`. ## Steps to Reproduce 1. Register an actor: `agents actor add --config ./actors/my-actor.yaml` 2. Run the same command again without `--update`: `agents actor add --config ./actors/my-actor.yaml` 3. **Expected**: Command fails with error panel "Actor already exists: ..." 4. **Actual**: Command silently succeeds, updating the existing actor ## Expected Behavior When `--update` is not provided and actor already exists: - Exit code: 1 - Display error panel with actor name, registration date, and hint to use `--update` - Print `✗ ERROR Actor already registered — use --update to replace` ## Code Location - `src/cleveragents/cli/commands/actor.py`, `add()` function (lines ~563–597) - The fix is to either: a. Call `registry.add(yaml_text, update=update_existing)` instead of `registry.upsert_actor()` b. Or add a pre-check: if not `update_existing`, check if actor exists and fail with the spec-required error panel ## Subtasks - [ ] Investigate `add()` in `src/cleveragents/cli/commands/actor.py` and confirm the upsert bypass - [ ] Fix CLI `add()` to call `registry.add(yaml_text, update=update_existing)` or add a pre-existence check - [ ] Render the spec-required Rich error panel when duplicate is detected without `--update` - [ ] Ensure exit code 1 is returned on duplicate detection - [ ] Tests (Behave): Add scenario — `agents actor add` without `--update` on existing actor fails with error panel - [ ] Tests (Behave): Add scenario — `agents actor add --update` on existing actor succeeds - [ ] Tests (Robot): Add integration test for duplicate detection in `actor add` - [ ] Verify coverage >= 97% via `nox -e coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done - [ ] All subtasks above are completed and checked off - [ ] `agents actor add` (without `--update`) on an existing actor exits with code 1 and displays the spec-required error panel - [ ] `agents actor add --update` on an existing actor succeeds as before - [ ] A Git commit is created where the first line matches the Commit Message in Metadata exactly, with `ISSUES CLOSED: #<N>` in the footer - [ ] The commit is pushed to the branch matching the Branch in Metadata exactly - [ ] The commit is submitted as a pull request to `master`, reviewed, and merged before this issue is marked done - [ ] All nox stages pass - [ ] Coverage >= 97% --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
Author
Owner

Closing as duplicate of #3426.

Both issues describe the same root cause: agents actor add calls registry.upsert_actor() instead of registry.add(). Issue #3426 covers the YAML-first path bypass (which includes the duplicate detection fix, since ActorRegistry.add() implements duplicate detection correctly). Issue #3426 is already State/In Review with PR #3462 submitted. Please track this work in #3426.


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

Closing as duplicate of #3426. Both issues describe the same root cause: `agents actor add` calls `registry.upsert_actor()` instead of `registry.add()`. Issue #3426 covers the YAML-first path bypass (which includes the duplicate detection fix, since `ActorRegistry.add()` implements duplicate detection correctly). Issue #3426 is already `State/In Review` with PR #3462 submitted. Please track this work in #3426. --- **Automated by CleverAgents Bot** Supervisor: Backlog Grooming | Agent: ca-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.

Blocks
#392 Epic: Actor YAML & Compiler
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3481
No description provided.