agents actor list without actors should show no actors. #592

Closed
opened 2026-03-05 01:23:51 +00:00 by brent.edwards · 4 comments
Member

Metadata

  • Commit Message: fix(actor): handle empty actor list without validation error
  • Branch: feature/m3-fix-actor-list-empty
Field Value
Type Bug
Priority Medium
MoSCoW Must Have
Points 3
Milestone v3.2.0
Assignee freemo
Parent Epic #401

Background and Context

Running agents actor list in a fresh environment (no actors configured) throws a ValidationError: Actor names must include exactly one '/' separator. The root cause is that ActorRegistry.list_actors() calls ensure_built_in_actors() which constructs actor names using provider default model names. Some providers (e.g., OpenRouter) have model names containing / (like anthropic/claude-sonnet-4-20250514), resulting in actor names with multiple / separators that fail validation in ActorService._normalize_name().

Reported by Brent Edwards on Day 25.

Steps to reproduce:

cd ~
mkdir data
uv venv
source .venv/bin/activate
uv pip install -e /app
agents init
agents actor list
# Expected: "No actors found" or empty list
# Actual: Error [422] VALIDATION_FAILED: Actor names must include exactly one '/' separator

Expected Behavior

agents actor list with no configured actors should return an empty list or a "No actors found" message without errors.

Acceptance Criteria

  • agents actor list with zero providers returns an empty list without error.
  • agents actor list with providers whose model names contain / does not trigger validation errors.
  • Actor name construction handles multi-slash model names gracefully.

Subtasks

  • Code: Fix name construction in ensure_built_in_actors() or _normalize_name() to handle multi-slash model names.
  • Tests (Behave): Ensure failing tests from PR #594 now pass.
  • Tests (Robot): Ensure Robot smoke tests pass.
  • Quality: Verify coverage >=97% via nox -s coverage_report.
  • Quality: Run nox (all default sessions), fix any errors.

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly.
  • The commit is pushed to the remote on 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.
## Metadata - **Commit Message**: `fix(actor): handle empty actor list without validation error` - **Branch**: `feature/m3-fix-actor-list-empty` | Field | Value | |-------|-------| | **Type** | Bug | | **Priority** | Medium | | **MoSCoW** | Must Have | | **Points** | 3 | | **Milestone** | v3.2.0 | | **Assignee** | freemo | | **Parent Epic** | #401 | ## Background and Context Running `agents actor list` in a fresh environment (no actors configured) throws a `ValidationError: Actor names must include exactly one '/' separator`. The root cause is that `ActorRegistry.list_actors()` calls `ensure_built_in_actors()` which constructs actor names using provider default model names. Some providers (e.g., OpenRouter) have model names containing `/` (like `anthropic/claude-sonnet-4-20250514`), resulting in actor names with multiple `/` separators that fail validation in `ActorService._normalize_name()`. Reported by Brent Edwards on Day 25. **Steps to reproduce:** ```bash cd ~ mkdir data uv venv source .venv/bin/activate uv pip install -e /app agents init agents actor list # Expected: "No actors found" or empty list # Actual: Error [422] VALIDATION_FAILED: Actor names must include exactly one '/' separator ``` ## Expected Behavior `agents actor list` with no configured actors should return an empty list or a "No actors found" message without errors. ## Acceptance Criteria - [ ] `agents actor list` with zero providers returns an empty list without error. - [ ] `agents actor list` with providers whose model names contain `/` does not trigger validation errors. - [ ] Actor name construction handles multi-slash model names gracefully. ## Subtasks - [ ] Code: Fix name construction in `ensure_built_in_actors()` or `_normalize_name()` to handle multi-slash model names. - [ ] Tests (Behave): Ensure failing tests from PR #594 now pass. - [ ] Tests (Robot): Ensure Robot smoke tests pass. - [ ] Quality: Verify coverage >=97% via `nox -s coverage_report`. - [ ] Quality: Run `nox` (all default sessions), fix any errors. ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly. - The commit is pushed to the remote on 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.
brent.edwards added this to the v3.2.0 milestone 2026-03-05 01:23:51 +00:00
Author
Member

TDD Tests Submitted -- PR #594

Opened PR #594 with TDD failing tests that reproduce this bug.

Root Cause Analysis

ActorRegistry.list_actors() at registry.py:324-327 unconditionally calls ensure_built_in_actors() before listing. That method iterates configured providers and builds actor names via _actor_name(provider, model) which produces f"{provider}/{model}". For providers whose default model already contains / (e.g. OpenRouter's anthropic/claude-sonnet-4-20250514), this yields names like Openrouter/anthropic/claude-sonnet-4-20250514 (2+ slashes). ActorService.upsert_actor() at actor_service.py:60 then calls _normalize_name() at line 26 which raises ValidationError("Actor names must include exactly one '/' separator").

This means a read-only actor list operation triggers write-path validation that fails.

Deliverables

  • 3 Behave BDD scenarios (@wip, @tdd, @bug592) -- scenario 3 exercises the real buggy code path
  • Robot Framework integration smoke tests
  • ASV benchmarks with multi-slash success tracker
  • CHANGELOG entry

Suggested Fixes

The bug-fix author could:

  1. Fix _normalize_name() to allow multi-slash names for built-in actors (e.g. allow_multi_slash=True)
  2. Fix _actor_name() to replace additional / in model names (e.g. model.replace("/", "-"))
  3. Skip ensure_built_in_actors() on the list path and call it lazily elsewhere
## TDD Tests Submitted -- PR #594 Opened PR #594 with TDD failing tests that reproduce this bug. ### Root Cause Analysis `ActorRegistry.list_actors()` at `registry.py:324-327` unconditionally calls `ensure_built_in_actors()` before listing. That method iterates configured providers and builds actor names via `_actor_name(provider, model)` which produces `f"{provider}/{model}"`. For providers whose default model already contains `/` (e.g. OpenRouter's `anthropic/claude-sonnet-4-20250514`), this yields names like `Openrouter/anthropic/claude-sonnet-4-20250514` (2+ slashes). `ActorService.upsert_actor()` at `actor_service.py:60` then calls `_normalize_name()` at line 26 which raises `ValidationError("Actor names must include exactly one '/' separator")`. This means a read-only `actor list` operation triggers write-path validation that fails. ### Deliverables - 3 Behave BDD scenarios (`@wip`, `@tdd`, `@bug592`) -- scenario 3 exercises the real buggy code path - Robot Framework integration smoke tests - ASV benchmarks with multi-slash success tracker - CHANGELOG entry ### Suggested Fixes The bug-fix author could: 1. Fix `_normalize_name()` to allow multi-slash names for built-in actors (e.g. `allow_multi_slash=True`) 2. Fix `_actor_name()` to replace additional `/` in model names (e.g. `model.replace("/", "-")`) 3. Skip `ensure_built_in_actors()` on the list path and call it lazily elsewhere
Owner

PM Acknowledgment — Day 25 Review

Excellent root cause analysis, @brent.edwards. The multi-slash actor name validation failure on a read-only path is a clear bug — actor list should never trigger write-path validation.

Triage Notes

  • TDD PR #594 assigned to @freemo for review and fix implementation.
  • Fix approach: Brent's Option 2 (model.replace("/", "-") in _actor_name()) is the cleanest — it normalizes at the source without weakening validation elsewhere. Option 3 (skip ensure_built_in_actors() on list path) is also viable but changes the lazy-init contract.
  • Priority: Medium — this is a user-visible regression in M3.

Fix Ownership

@freemo — please review PR #594 and implement the fix. The root cause is isolated to registry.py:324-327 and actor_service.py:26.

## PM Acknowledgment — Day 25 Review Excellent root cause analysis, @brent.edwards. The multi-slash actor name validation failure on a read-only path is a clear bug — `actor list` should never trigger write-path validation. ### Triage Notes - **TDD PR #594** assigned to @freemo for review and fix implementation. - **Fix approach**: Brent's Option 2 (`model.replace("/", "-")` in `_actor_name()`) is the cleanest — it normalizes at the source without weakening validation elsewhere. Option 3 (skip `ensure_built_in_actors()` on list path) is also viable but changes the lazy-init contract. - **Priority**: Medium — this is a user-visible regression in M3. ### Fix Ownership @freemo — please review PR #594 and implement the fix. The root cause is isolated to `registry.py:324-327` and `actor_service.py:26`.
Owner

Implementation Notes

Root Cause

ActorRegistry._actor_name() constructs actor names using provider model names directly. Some providers (OpenRouter) have model names containing / (e.g., anthropic/claude-sonnet-4-20250514), producing actor names like Openrouter/anthropic/claude-sonnet-4-20250514 with multiple / separators. ActorService._normalize_name() requires exactly one / and throws ValidationError.

Fix Applied

Modified ActorRegistry._actor_name() to sanitize model names: sanitized_model = model_name.replace("/", "-"). This converts anthropic/claude-sonnet-4-20250514 to anthropic-claude-sonnet-4-20250514, producing valid actor names like Openrouter/anthropic-claude-sonnet-4-20250514.

Also fixed the test's _FakeProviderInfo to use a real ProviderCapabilities dataclass instead of MagicMock so dataclasses.asdict() works correctly.

Verification

  • All nox sessions pass, coverage 97%
  • 8503 Behave scenarios, 1196 Robot tests (0 failures)

PR: #594 (updated with fix commit)

## Implementation Notes ### Root Cause `ActorRegistry._actor_name()` constructs actor names using provider model names directly. Some providers (OpenRouter) have model names containing `/` (e.g., `anthropic/claude-sonnet-4-20250514`), producing actor names like `Openrouter/anthropic/claude-sonnet-4-20250514` with multiple `/` separators. `ActorService._normalize_name()` requires exactly one `/` and throws `ValidationError`. ### Fix Applied Modified `ActorRegistry._actor_name()` to sanitize model names: `sanitized_model = model_name.replace("/", "-")`. This converts `anthropic/claude-sonnet-4-20250514` to `anthropic-claude-sonnet-4-20250514`, producing valid actor names like `Openrouter/anthropic-claude-sonnet-4-20250514`. Also fixed the test's `_FakeProviderInfo` to use a real `ProviderCapabilities` dataclass instead of `MagicMock` so `dataclasses.asdict()` works correctly. ### Verification - All nox sessions pass, coverage 97% - 8503 Behave scenarios, 1196 Robot tests (0 failures) PR: #594 (updated with fix commit)
Owner

PM Note — Dependency Added

This bug fix is blocked by TDD issue #634 per the mandatory TDD workflow in CONTRIBUTING.md. The failing test scaffolding must be merged before the fix can proceed.

Dependencies:

  • Blocked by: #634 (TDD failing tests for actor list validation)
  • Transitively blocked by: #627 (Behave @tdd_expected_fail tags), #628 (Robot tdd_expected_fail tags)
**PM Note — Dependency Added** This bug fix is **blocked by** TDD issue #634 per the mandatory TDD workflow in CONTRIBUTING.md. The failing test scaffolding must be merged before the fix can proceed. **Dependencies:** - Blocked by: #634 (TDD failing tests for actor list validation) - Transitively blocked by: #627 (Behave `@tdd_expected_fail` tags), #628 (Robot `tdd_expected_fail` tags)
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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#592
No description provided.