zeroclaw-labs/zeroclaw · error · anyhow::Error

Skill front-matter missing required `name` field

Error message

Skill front-matter missing required `name` field

What it means

Front-matter was found, but front_matter_value found no top-level 'name:' key, or one whose value is empty after quote stripping. name is the only required front-matter field for a skill the improver is allowed to write back.

Source

Thrown at crates/zeroclaw-runtime/src/skills/improver.rs:145

    fn skills_dir(&self) -> PathBuf {
        self.workspace_dir.join("skills")
    }
}

/// Validate skill content: must be non-empty, have a parseable YAML front-matter
/// block with a non-empty `name` field.
pub fn validate_skill_content(content: &str) -> Result<()> {
    if content.trim().is_empty() {
        bail!("Skill content is empty");
    }

    let Some((front, _body)) = split_front_matter(content) else {
        bail!("Skill content is missing YAML front-matter (expected `---` delimited block at top)");
    };

    let name = front_matter_value(&front, "name").unwrap_or_default();
    if name.trim().is_empty() {
        bail!("Skill front-matter missing required `name` field");
    }

    Ok(())
}

/// Split a SKILL.md into (front_matter_text, body_text).
/// Returns `None` if the file doesn't start with `---\n` or has no closing
/// `---` delimiter.
fn split_front_matter(content: &str) -> Option<(String, String)> {
    let normalized = content.replace("\r\n", "\n");
    let rest = normalized.strip_prefix("---\n")?;
    if let Some(idx) = rest.find("\n---\n") {
        Some((rest[..idx].to_string(), rest[idx + 5..].to_string()))
    } else {
        rest.strip_suffix("\n---")
            .map(|front| (front.to_string(), String::new()))
    }
}

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Add an unindented top-level line 'name: <value>' inside the front-matter
  2. Give it a real value: name: \"\" also fails the empty check
  3. If name is nested (e.g., under metadata:), move it to the top level
  4. Pre-validate with the public validate_skill_content before calling improve_skill

Example fix

# before
---
title: deploy-guide
---

# after
---
name: deploy-guide
---
Defensive patterns

Strategy: type-guard

Validate before calling

zeroclaw_runtime::skills::validate_skill_content(&improved_content)?; // rejects missing name too

Type guard

fn front_matter_has_name(content: &str) -> bool {
    let n = content.replace("\r\n", "\n");
    let Some(rest) = n.strip_prefix("---\n") else { return false };
    let front = rest.split("\n---\n").next().unwrap_or(rest);
    front.lines().any(|l| {
        !l.starts_with(' ') && !l.starts_with('\t')
            && l.starts_with("name:")
            && l[5..].trim().trim_matches('"').trim_matches('\'').trim().len() > 0
    })
}

Prevention

When it happens

Trigger: Front-matter with no name key at all; 'name:' with an empty value or empty quotes; name nested under another mapping (indented lines are skipped by the flat key parser); a differently spelled key such as title or skill_name.

Common situations: LLM improvement that renames or drops the field; templates that use title instead of name; YAML where name sits under a nested metadata: block.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/0ee4ca6e3576512e. Report an issue: GitHub.