Skip to content

fix(VIOL-0064): raise on ambiguous agent-name folder match#767

Merged
Muizzkolapo merged 1 commit into
mainfrom
fix/viol-0064-action-name-disambiguation
Jul 6, 2026
Merged

fix(VIOL-0064): raise on ambiguous agent-name folder match#767
Muizzkolapo merged 1 commit into
mainfrom
fix/viol-0064-action-name-disambiguation

Conversation

@Muizzkolapo

Copy link
Copy Markdown
Owner

Summary

The agent-name resolver (FileHandler.get_agent_paths) walked the project tree and returned the first <name>/agent_config directory it happened to reach, silently. In a project where two directories share the same base name (multi-tenant / multi-workflow layouts), an operator running any CLI command with -a <name> could target the wrong workflow — reading and writing the wrong agent_io — with no warning or error.

Root cause: a first-match return inside os.walk.

Fix:

  • Add FileHandler.find_all_specific_folders — collects every matching folder instead of returning the first.
  • get_agent_paths now raises AmbiguousAgentName listing every candidate (full path + parent workflow directory) when two or more agent_config directories share the base name.
  • 0-match and 1-match behavior is byte-identical ((None, None) and the single path, respectively).
  • find_specific_folder (first-match) is left intact for the agent_io lookup and action-folder resolution — the agent_config raise fires first and covers the common case.

Why AmbiguousAgentName subclasses ValidationError: the sole caller (ProjectPathsFactory.get_agent_paths) re-raises ValidationError unchanged but wraps any other exception into a generic "Failed to get agent paths" message that would destroy the candidate list. Subclassing ValidationError lets the precise error — with its full candidate listing — propagate cleanly to every CLI command via create_project_paths, with no caller edit. This also aligns the ≥2-match case with the existing 0-match case, which already surfaces as a ValidationError.

Verification

  • RED: the two ambiguous-fixture tests failed with DID NOT RAISE (proving the silent first-match bug), while single/zero/subclass baselines passed.
  • GREEN: all five tests in tests/unit/utils/test_get_agent_paths_disambiguation.py pass after the fix, at both the util layer and the CLI-facing factory layer (candidate list survives, not re-wrapped).
  • No regression: tests/unit/test_errors.py, tests/unit/utils/, tests/cli/test_cli_hardening.py (incl. the single-match test_project_root_reaches_file_handler), tests/workflow/test_runner.py, tests/unit/llm_invocation/test_agent_manager.py, tests/config/ — all pass.
  • ruff check clean; ruff format --check clean.

Out of scope (follow-up)

agent_io ambiguity is not guarded — the agent_config raise fires first. Guard it the same way if a case arises. The separate AgentManager realtime resolver is a different code path and is untouched.

The agent-name resolver walked the project tree and returned the FIRST
`<name>/agent_config` directory it happened to reach, silently. In a
project where two directories share the same base name (multi-tenant or
multi-workflow layouts), an operator passing `-a <name>` could target the
wrong workflow — reading and writing the wrong agent_io — with no warning.

Root cause: a first-match `return` inside `os.walk`. The fix adds a plural
collector that gathers every matching `agent_config` folder and raises
`AmbiguousAgentName` listing all candidates when two or more share the base
name. Zero-match and single-match behavior is byte-identical (still
`(None, None)` and the single path respectively).

`AmbiguousAgentName` subclasses `ValidationError` deliberately: the sole
caller wraps the resolver in `except ValidationError: raise` but re-wraps
any other exception into a generic "Failed to get agent paths" message that
would destroy the candidate list. Subclassing `ValidationError` lets the
precise ambiguity error — with its full candidate listing — propagate
cleanly to every CLI command with no change to the caller. This also aligns
the two-or-more-match case with the existing zero-match case, which already
surfaces as a `ValidationError`.
@Muizzkolapo Muizzkolapo merged commit 957f34d into main Jul 6, 2026
5 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant