BUG-HUNT: [error-handling] discovery._skill_from_front_matter silently falls back to folder name when SKILL.md lacks name field — no namespace/name format validation applied to fallback #6600

Open
opened 2026-04-09 22:00:14 +00:00 by HAL9000 · 0 comments
Owner

Bug Report: Error Handling / Boundary — Unvalidated Folder-Name Fallback in Discovery

Severity Assessment

  • Impact: When a SKILL.md file is missing the name field, the discovery system silently substitutes the folder's base name (e.g., my_deploy_skill) as the skill name. This raw folder name is not validated against the required namespace/name format. The resulting DiscoveredAgentSkill.name is an unnamespaced string, which then gets registered as agent_skills/my_deploy_skill — but if the folder name contains characters that violate the naming convention (spaces, dots, uppercase letters, slashes), the tool name will be invalid. Worse, there is no warning to the user that the required name field was absent.
  • Likelihood: Medium — SKILL.md files without a name field (e.g., during initial authoring or migration) silently produce malformed skill registrations.
  • Priority: Medium

Location

  • File: src/cleveragents/skills/discovery.py
  • Function: _skill_from_front_matter
  • Lines: ~130–144

Description

# discovery.py  lines 130–144
def _skill_from_front_matter(
    data: dict[str, Any],
    folder_path: Path,
) -> DiscoveredAgentSkill | None:
    name = data.get("name")
    if not name or not isinstance(name, str):
        # Fall back to folder name
        name = folder_path.name    # ← raw folder name, NO validation
    ...
    return DiscoveredAgentSkill(
        name=name,          # ← potentially invalid name stored
        ...
    )

The AgentSkillSpec.from_string() path (used by AgentSkillLoader) does validate the name via _NAMESPACED_NAME_RE. But the discovery.py code path used by scan_directory() and discover_agent_skills() does not apply any format validation to the fallback name.

This leads to three problems:

  1. Silent data quality degradation: A missing name field is never logged at WARNING level — only a DEBUG log is emitted for missing front-matter.
  2. Invalid tool names in registry: Folder names with spaces, uppercase letters, dots, or other invalid characters produce tool names like agent_skills/My Deploy Skill which would fail any downstream name validation.
  3. Inconsistency: Two code paths that do the same thing (AgentSkillSpec.from_string vs discovery._skill_from_front_matter) apply different validation rules.

Evidence

# A folder named "Deploy.Staging" with no 'name' in SKILL.md:
folder_path.name = "Deploy.Staging"
name = folder_path.name   # → "Deploy.Staging"
# No validation — registered as "agent_skills/Deploy.Staging"
# The dot makes this an invalid namespaced name per the spec

Expected Behavior

If the name field is missing from a SKILL.md:

  1. The error should be logged at WARNING (not just DEBUG) with the path and missing field.
  2. Either: the skill is skipped with a DiscoveryResult.errors entry, OR the fallback name is validated against the namespace/name pattern before use.

Actual Behavior

The folder name is used as-is without validation, and no warning is emitted.

Suggested Fix

def _skill_from_front_matter(
    data: dict[str, Any],
    folder_path: Path,
) -> DiscoveredAgentSkill | None:
    name = data.get("name")
    if not name or not isinstance(name, str):
        logger.warning(
            "SKILL.md at '%s' is missing required 'name' field; "
            "falling back to folder name '%s'",
            folder_path / "SKILL.md",
            folder_path.name,
        )
        name = folder_path.name
    
    # Validate name format regardless of source
    if not re.match(r"^[a-z0-9][a-z0-9_-]*/[a-z0-9][a-z0-9_-]*$", name):
        # Folder names won't have a namespace — skip the skill with an error
        logger.warning(
            "Skipping agent skill at '%s': name '%s' does not follow "
            "namespace/name format",
            folder_path,
            name,
        )
        return None
    ...

Category

error-handling

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_, and @tdd_expected_fail to prove the bug exists before fixing it.


Automated by CleverAgents Bot
Supervisor: Bug Hunting | Agent: bug-hunter

## Bug Report: Error Handling / Boundary — Unvalidated Folder-Name Fallback in Discovery ### Severity Assessment - **Impact**: When a `SKILL.md` file is missing the `name` field, the discovery system silently substitutes the folder's base name (e.g., `my_deploy_skill`) as the skill name. This raw folder name is not validated against the required `namespace/name` format. The resulting `DiscoveredAgentSkill.name` is an unnamespaced string, which then gets registered as `agent_skills/my_deploy_skill` — but if the folder name contains characters that violate the naming convention (spaces, dots, uppercase letters, slashes), the tool name will be invalid. Worse, there is no warning to the user that the required `name` field was absent. - **Likelihood**: Medium — SKILL.md files without a `name` field (e.g., during initial authoring or migration) silently produce malformed skill registrations. - **Priority**: Medium ### Location - **File**: `src/cleveragents/skills/discovery.py` - **Function**: `_skill_from_front_matter` - **Lines**: ~130–144 ### Description ```python # discovery.py lines 130–144 def _skill_from_front_matter( data: dict[str, Any], folder_path: Path, ) -> DiscoveredAgentSkill | None: name = data.get("name") if not name or not isinstance(name, str): # Fall back to folder name name = folder_path.name # ← raw folder name, NO validation ... return DiscoveredAgentSkill( name=name, # ← potentially invalid name stored ... ) ``` The `AgentSkillSpec.from_string()` path (used by `AgentSkillLoader`) **does** validate the name via `_NAMESPACED_NAME_RE`. But the `discovery.py` code path used by `scan_directory()` and `discover_agent_skills()` does **not** apply any format validation to the fallback name. This leads to three problems: 1. **Silent data quality degradation**: A missing `name` field is never logged at WARNING level — only a `DEBUG` log is emitted for missing front-matter. 2. **Invalid tool names in registry**: Folder names with spaces, uppercase letters, dots, or other invalid characters produce tool names like `agent_skills/My Deploy Skill` which would fail any downstream name validation. 3. **Inconsistency**: Two code paths that do the same thing (`AgentSkillSpec.from_string` vs `discovery._skill_from_front_matter`) apply different validation rules. ### Evidence ```python # A folder named "Deploy.Staging" with no 'name' in SKILL.md: folder_path.name = "Deploy.Staging" name = folder_path.name # → "Deploy.Staging" # No validation — registered as "agent_skills/Deploy.Staging" # The dot makes this an invalid namespaced name per the spec ``` ### Expected Behavior If the `name` field is missing from a `SKILL.md`: 1. The error should be logged at WARNING (not just DEBUG) with the path and missing field. 2. Either: the skill is **skipped** with a `DiscoveryResult.errors` entry, OR the fallback name is validated against the `namespace/name` pattern before use. ### Actual Behavior The folder name is used as-is without validation, and no warning is emitted. ### Suggested Fix ```python def _skill_from_front_matter( data: dict[str, Any], folder_path: Path, ) -> DiscoveredAgentSkill | None: name = data.get("name") if not name or not isinstance(name, str): logger.warning( "SKILL.md at '%s' is missing required 'name' field; " "falling back to folder name '%s'", folder_path / "SKILL.md", folder_path.name, ) name = folder_path.name # Validate name format regardless of source if not re.match(r"^[a-z0-9][a-z0-9_-]*/[a-z0-9][a-z0-9_-]*$", name): # Folder names won't have a namespace — skip the skill with an error logger.warning( "Skipping agent skill at '%s': name '%s' does not follow " "namespace/name format", folder_path, name, ) return None ... ``` ### Category error-handling ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: bug-hunter
HAL9000 added this to the v3.2.0 milestone 2026-04-09 22:13:19 +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.

Dependencies

No dependencies set.

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