UAT: SkillRegistry.validate_skill() and validate_plan() crash with AttributeError — call get_tool() on ToolRegistry which has no such method #1843

Open
opened 2026-04-02 23:57:10 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/uat-skill-registry-validate-get-tool-attribute-error
  • Commit Message: fix(skills): replace get_tool() with get() in SkillRegistry.validate_skill() and validate_plan()
  • Milestone: v3.7.0
  • Parent Epic: #374

Background and Context

Per docs/specification.md, the Skill Registry is responsible for validating that tool references in a skill definition exist in the Tool Registry. The validate_skill() method should return a list of validation error messages, and validate_plan() should return a list of errors for plan-level skill validation.

The SkillRegistry class in src/cleveragents/skills/registry.py calls self._tool_registry.get_tool(ref) in both validate_skill() (line ~371) and validate_plan() (line ~42). However, ToolRegistry (in src/cleveragents/tool/registry.py) only exposes a get() method — there is no get_tool() method. This causes an AttributeError crash on every invocation of these two methods when a ToolRegistry is configured.

Notably, the refresh() method in the same SkillRegistry class correctly uses self._tool_registry.get(entry.name) — only validate_skill() and validate_plan() have this inconsistency.

Current Behavior

Both validate_skill() and validate_plan() raise AttributeError: 'ToolRegistry' object has no attribute 'get_tool' when called with a ToolRegistry instance configured.

Reproduction:

from cleveragents.skills.registry import SkillRegistry
from cleveragents.skills.protocol import SkillDefinition, SkillMetadata
from cleveragents.domain.models.core.skill import Skill
from cleveragents.tool.registry import ToolRegistry
from cleveragents.tool.runtime import ToolSpec

tool_registry = ToolRegistry()
tool_spec = ToolSpec(name='local/read-file', description='Read file', handler=lambda: None)
tool_registry.register(tool_spec)

skill_registry = SkillRegistry(tool_registry=tool_registry)

skill = Skill(name='local/test-skill', description='Test skill', tool_refs=['local/read-file'])
metadata = SkillMetadata(name='local/test-skill', description='Test skill')
defn = SkillDefinition(skill=skill, metadata=metadata)

# Crashes with AttributeError:
errors = skill_registry.validate_skill(defn)
# AttributeError: 'ToolRegistry' object has no attribute 'get_tool'

skill_registry.register(defn)
errors = skill_registry.validate_plan({'skills': ['local/test-skill']})
# AttributeError: 'ToolRegistry' object has no attribute 'get_tool'

Expected Behavior

  • validate_skill(defn) returns a list of validation error strings (empty list if all tool refs resolve correctly).
  • validate_plan(plan) returns a list of validation error strings (empty list if all skill tool refs resolve correctly).
  • No AttributeError is raised; the correct ToolRegistry.get() method is called instead of the non-existent get_tool().

Root Cause

In src/cleveragents/skills/registry.py:

  • Line ~371 in validate_skill(): tool = self._tool_registry.get_tool(ref) → should be self._tool_registry.get(ref)
  • Line ~42 in validate_plan(): tool = self._tool_registry.get_tool(entry.name) → should be self._tool_registry.get(entry.name)

The refresh() method in the same file already uses the correct self._tool_registry.get(entry.name) call, confirming the intended API.

Impact

  • SkillRegistry.validate_skill() is completely broken when a ToolRegistry is configured.
  • SkillRegistry.validate_plan() is completely broken when a ToolRegistry is configured.
  • Any code path that calls these methods will crash with AttributeError.

Subtasks

  • In src/cleveragents/skills/registry.py, replace self._tool_registry.get_tool(ref) with self._tool_registry.get(ref) in validate_skill() (~line 371)
  • In src/cleveragents/skills/registry.py, replace self._tool_registry.get_tool(entry.name) with self._tool_registry.get(entry.name) in validate_plan() (~line 42)
  • Verify no other occurrences of get_tool() exist on ToolRegistry calls in the codebase
  • Add/update Behave unit tests in features/ to cover validate_skill() and validate_plan() with a configured ToolRegistry
  • Run nox -e typecheck to confirm Pyright passes with no errors
  • Run nox -e unit_tests to confirm all Behave tests pass
  • Run nox -e coverage_report to confirm coverage ≥ 97%

Definition of Done

  • SkillRegistry.validate_skill() no longer raises AttributeError when called with a ToolRegistry configured
  • SkillRegistry.validate_plan() no longer raises AttributeError when called with a ToolRegistry configured
  • Both methods correctly call self._tool_registry.get() (consistent with refresh())
  • Behave unit tests cover both the happy path (tool ref resolves) and the error path (tool ref missing) for validate_skill() and validate_plan()
  • All nox stages pass
  • Coverage >= 97%

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

## Metadata - **Branch**: `fix/uat-skill-registry-validate-get-tool-attribute-error` - **Commit Message**: `fix(skills): replace get_tool() with get() in SkillRegistry.validate_skill() and validate_plan()` - **Milestone**: v3.7.0 - **Parent Epic**: #374 ## Background and Context Per `docs/specification.md`, the Skill Registry is responsible for validating that tool references in a skill definition exist in the Tool Registry. The `validate_skill()` method should return a list of validation error messages, and `validate_plan()` should return a list of errors for plan-level skill validation. The `SkillRegistry` class in `src/cleveragents/skills/registry.py` calls `self._tool_registry.get_tool(ref)` in both `validate_skill()` (line ~371) and `validate_plan()` (line ~42). However, `ToolRegistry` (in `src/cleveragents/tool/registry.py`) only exposes a `get()` method — there is no `get_tool()` method. This causes an `AttributeError` crash on every invocation of these two methods when a `ToolRegistry` is configured. Notably, the `refresh()` method in the same `SkillRegistry` class correctly uses `self._tool_registry.get(entry.name)` — only `validate_skill()` and `validate_plan()` have this inconsistency. ## Current Behavior Both `validate_skill()` and `validate_plan()` raise `AttributeError: 'ToolRegistry' object has no attribute 'get_tool'` when called with a `ToolRegistry` instance configured. **Reproduction:** ```python from cleveragents.skills.registry import SkillRegistry from cleveragents.skills.protocol import SkillDefinition, SkillMetadata from cleveragents.domain.models.core.skill import Skill from cleveragents.tool.registry import ToolRegistry from cleveragents.tool.runtime import ToolSpec tool_registry = ToolRegistry() tool_spec = ToolSpec(name='local/read-file', description='Read file', handler=lambda: None) tool_registry.register(tool_spec) skill_registry = SkillRegistry(tool_registry=tool_registry) skill = Skill(name='local/test-skill', description='Test skill', tool_refs=['local/read-file']) metadata = SkillMetadata(name='local/test-skill', description='Test skill') defn = SkillDefinition(skill=skill, metadata=metadata) # Crashes with AttributeError: errors = skill_registry.validate_skill(defn) # AttributeError: 'ToolRegistry' object has no attribute 'get_tool' skill_registry.register(defn) errors = skill_registry.validate_plan({'skills': ['local/test-skill']}) # AttributeError: 'ToolRegistry' object has no attribute 'get_tool' ``` ## Expected Behavior - `validate_skill(defn)` returns a list of validation error strings (empty list if all tool refs resolve correctly). - `validate_plan(plan)` returns a list of validation error strings (empty list if all skill tool refs resolve correctly). - No `AttributeError` is raised; the correct `ToolRegistry.get()` method is called instead of the non-existent `get_tool()`. ## Root Cause In `src/cleveragents/skills/registry.py`: - **Line ~371** in `validate_skill()`: `tool = self._tool_registry.get_tool(ref)` → should be `self._tool_registry.get(ref)` - **Line ~42** in `validate_plan()`: `tool = self._tool_registry.get_tool(entry.name)` → should be `self._tool_registry.get(entry.name)` The `refresh()` method in the same file already uses the correct `self._tool_registry.get(entry.name)` call, confirming the intended API. ## Impact - `SkillRegistry.validate_skill()` is completely broken when a `ToolRegistry` is configured. - `SkillRegistry.validate_plan()` is completely broken when a `ToolRegistry` is configured. - Any code path that calls these methods will crash with `AttributeError`. ## Subtasks - [ ] In `src/cleveragents/skills/registry.py`, replace `self._tool_registry.get_tool(ref)` with `self._tool_registry.get(ref)` in `validate_skill()` (~line 371) - [ ] In `src/cleveragents/skills/registry.py`, replace `self._tool_registry.get_tool(entry.name)` with `self._tool_registry.get(entry.name)` in `validate_plan()` (~line 42) - [ ] Verify no other occurrences of `get_tool()` exist on `ToolRegistry` calls in the codebase - [ ] Add/update Behave unit tests in `features/` to cover `validate_skill()` and `validate_plan()` with a configured `ToolRegistry` - [ ] Run `nox -e typecheck` to confirm Pyright passes with no errors - [ ] Run `nox -e unit_tests` to confirm all Behave tests pass - [ ] Run `nox -e coverage_report` to confirm coverage ≥ 97% ## Definition of Done - [ ] `SkillRegistry.validate_skill()` no longer raises `AttributeError` when called with a `ToolRegistry` configured - [ ] `SkillRegistry.validate_plan()` no longer raises `AttributeError` when called with a `ToolRegistry` configured - [ ] Both methods correctly call `self._tool_registry.get()` (consistent with `refresh()`) - [ ] Behave unit tests cover both the happy path (tool ref resolves) and the error path (tool ref missing) for `validate_skill()` and `validate_plan()` - [ ] All nox stages pass - [ ] Coverage >= 97% --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.7.0 milestone 2026-04-02 23:58:22 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • MoSCoW: MoSCoW/Should Have — bug or error handling improvement.

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

Issue triaged by project owner: - **State**: Verified - **MoSCoW**: MoSCoW/Should Have — bug or error handling improvement. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
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.

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