UAT: register_resource() docstring claims it raises ValidationError for duplicate names but the implementation does not check for duplicate namespaced names #2838

Open
opened 2026-04-04 20:46:21 +00:00 by freemo · 0 comments
Owner

Background and Context

The register_resource() method in src/cleveragents/application/services/_resource_registry_ops.py carries a docstring that explicitly promises a ValidationError will be raised when a resource with the given name already exists in the registry. This is a public API contract that callers depend on for safe, idempotent resource registration. The contract is currently broken: the implementation skips the duplicate-name guard entirely, meaning callers cannot rely on the documented behaviour.

This was discovered during UAT testing of the Resource Abstraction & Registry feature area.

Current Behavior

The docstring states:

Raises:
    ValidationError: If the resource type is not user-addable,
        or if the resource name already exists.

However, the implementation proceeds directly from the user_addable check to ResourceModel creation without querying for an existing resource with the same namespaced_name. This produces one of two failure modes:

  1. If a unique constraint exists on namespaced_name: a raw sqlalchemy.exc.IntegrityError propagates to the caller instead of a clean ValidationError.
  2. If no unique constraint exists: duplicate names are silently allowed, corrupting the registry.

Steps to Reproduce

  1. Call service.register_resource("git-checkout", "local/my-repo", location="/tmp/repo")
  2. Call service.register_resource("git-checkout", "local/my-repo", location="/tmp/repo") again
  3. Observe: either a raw IntegrityError or a silent duplicate — not a clean ValidationError

Expected Behavior

When register_resource() is called with a name that already exists in the registry, it must raise ValidationError with a clear, user-facing message such as:

"Resource with name 'local/my-repo' already exists."

This is what the docstring promises and what consumers of the service layer expect.

Acceptance Criteria

  • register_resource() queries the repository for an existing resource whose namespaced_name matches the supplied name before attempting to create a new ResourceModel.
  • If a match is found, ValidationError is raised with a descriptive message identifying the duplicate name.
  • No raw sqlalchemy.exc.IntegrityError (or any other ORM-level exception) leaks to the caller for the duplicate-name case.
  • The docstring remains accurate and consistent with the implementation.
  • A Behave scenario covers the duplicate-name path and asserts the correct ValidationError is raised.
  • All existing tests continue to pass.

Supporting Information

  • File: src/cleveragents/application/services/_resource_registry_ops.py
  • Method: register_resource()
  • Severity: Medium — API contract violation; callers cannot rely on documented behaviour.
  • Related Epic: #398 (Post-MVP Resources)

Metadata

  • Branch: fix/resource-registry-duplicate-name-validation
  • Commit Message: fix(resource-registry): raise ValidationError for duplicate namespaced name in register_resource()
  • Milestone: v3.7.0
  • Parent Epic: #398

Subtasks

  • Locate the register_resource() method in _resource_registry_ops.py and identify the exact insertion point for the duplicate-name check
  • Add a repository query (e.g. get_by_namespaced_name) before ResourceModel creation to detect existing entries
  • Raise ValidationError with a clear message when a duplicate is detected
  • Update the docstring if any wording needs adjustment to stay accurate
  • Write a new Behave scenario in features/ covering the duplicate-name error path
  • Run nox -e lint, nox -e typecheck, nox -e unit_tests, nox -e coverage_report and confirm all pass

Definition of Done

  • Duplicate-name guard is implemented in register_resource() and raises ValidationError with a descriptive message
  • Docstring is consistent with the implementation
  • New Behave scenario exercises the duplicate-name path and asserts the correct exception type and message
  • No raw ORM exceptions leak to callers for the duplicate-name case
  • All nox stages pass (nox -e lint, nox -e typecheck, nox -e unit_tests, nox -e integration_tests, nox -e coverage_report)
  • Coverage >= 97%
  • Commit created with message fix(resource-registry): raise ValidationError for duplicate namespaced name in register_resource() and footer ISSUES CLOSED: #<this issue>
  • Pull request merged into the correct base branch and linked to this issue

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

## Background and Context The `register_resource()` method in `src/cleveragents/application/services/_resource_registry_ops.py` carries a docstring that explicitly promises a `ValidationError` will be raised when a resource with the given name already exists in the registry. This is a public API contract that callers depend on for safe, idempotent resource registration. The contract is currently broken: the implementation skips the duplicate-name guard entirely, meaning callers cannot rely on the documented behaviour. This was discovered during UAT testing of the Resource Abstraction & Registry feature area. ## Current Behavior The docstring states: ``` Raises: ValidationError: If the resource type is not user-addable, or if the resource name already exists. ``` However, the implementation proceeds directly from the `user_addable` check to `ResourceModel` creation **without** querying for an existing resource with the same `namespaced_name`. This produces one of two failure modes: 1. **If a unique constraint exists on `namespaced_name`**: a raw `sqlalchemy.exc.IntegrityError` propagates to the caller instead of a clean `ValidationError`. 2. **If no unique constraint exists**: duplicate names are silently allowed, corrupting the registry. ### Steps to Reproduce 1. Call `service.register_resource("git-checkout", "local/my-repo", location="/tmp/repo")` 2. Call `service.register_resource("git-checkout", "local/my-repo", location="/tmp/repo")` again 3. Observe: either a raw `IntegrityError` or a silent duplicate — not a clean `ValidationError` ## Expected Behavior When `register_resource()` is called with a `name` that already exists in the registry, it must raise `ValidationError` with a clear, user-facing message such as: ``` "Resource with name 'local/my-repo' already exists." ``` This is what the docstring promises and what consumers of the service layer expect. ## Acceptance Criteria - [ ] `register_resource()` queries the repository for an existing resource whose `namespaced_name` matches the supplied name before attempting to create a new `ResourceModel`. - [ ] If a match is found, `ValidationError` is raised with a descriptive message identifying the duplicate name. - [ ] No raw `sqlalchemy.exc.IntegrityError` (or any other ORM-level exception) leaks to the caller for the duplicate-name case. - [ ] The docstring remains accurate and consistent with the implementation. - [ ] A Behave scenario covers the duplicate-name path and asserts the correct `ValidationError` is raised. - [ ] All existing tests continue to pass. ## Supporting Information - **File**: `src/cleveragents/application/services/_resource_registry_ops.py` - **Method**: `register_resource()` - **Severity**: Medium — API contract violation; callers cannot rely on documented behaviour. - **Related Epic**: #398 (Post-MVP Resources) --- ## Metadata - **Branch**: `fix/resource-registry-duplicate-name-validation` - **Commit Message**: `fix(resource-registry): raise ValidationError for duplicate namespaced name in register_resource()` - **Milestone**: v3.7.0 - **Parent Epic**: #398 --- ## Subtasks - [ ] Locate the `register_resource()` method in `_resource_registry_ops.py` and identify the exact insertion point for the duplicate-name check - [ ] Add a repository query (e.g. `get_by_namespaced_name`) before `ResourceModel` creation to detect existing entries - [ ] Raise `ValidationError` with a clear message when a duplicate is detected - [ ] Update the docstring if any wording needs adjustment to stay accurate - [ ] Write a new Behave scenario in `features/` covering the duplicate-name error path - [ ] Run `nox -e lint`, `nox -e typecheck`, `nox -e unit_tests`, `nox -e coverage_report` and confirm all pass --- ## Definition of Done - [ ] Duplicate-name guard is implemented in `register_resource()` and raises `ValidationError` with a descriptive message - [ ] Docstring is consistent with the implementation - [ ] New Behave scenario exercises the duplicate-name path and asserts the correct exception type and message - [ ] No raw ORM exceptions leak to callers for the duplicate-name case - [ ] All nox stages pass (`nox -e lint`, `nox -e typecheck`, `nox -e unit_tests`, `nox -e integration_tests`, `nox -e coverage_report`) - [ ] Coverage >= 97% - [ ] Commit created with message `fix(resource-registry): raise ValidationError for duplicate namespaced name in register_resource()` and footer `ISSUES CLOSED: #<this issue>` - [ ] Pull request merged into the correct base branch and linked to this issue --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-uat-tester
freemo added this to the v3.7.0 milestone 2026-04-04 20:46:26 +00:00
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
#398 Epic: Post-MVP Resources
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#2838
No description provided.