zylon-ai/private-gpt · error · SkillDomainError

INVALID_FRONTMATTER

INVALID_FRONTMATTER

Error message

The SKILL.md frontmatter is not valid YAML.

What it means

After the frontmatter block is extracted, parse_skill_markdown runs yaml.safe_load on it; a YAMLError is caught and re-raised as SkillDomainError with code INVALID_FRONTMATTER ('The SKILL.md frontmatter is not valid YAML.'). The error is purely about YAML syntax inside the fences — the chained exception (__cause__) carries PyYAML's line/column diagnostics.

Source

Thrown at private_gpt/components/skills/parser.py:87

class ParsedSkillDocument(BaseModel):
    frontmatter: SkillFrontmatter
    body: str = Field(default="")


def parse_skill_markdown(skill_markdown: str) -> ParsedSkillDocument:
    match = _FRONTMATTER_RE.match(skill_markdown)
    if not match:
        raise SkillDomainError(
            SkillErrorCode.MISSING_FRONTMATTER,
            "SKILL.md must start with YAML frontmatter",
        )

    raw_frontmatter = match.group(1)
    try:
        parsed_yaml = yaml.safe_load(raw_frontmatter)
    except yaml.YAMLError as e:
        raise SkillDomainError(
            SkillErrorCode.INVALID_FRONTMATTER,
            "The SKILL.md frontmatter is not valid YAML.",
        ) from e
    if not isinstance(parsed_yaml, dict):
        raise SkillDomainError(
            SkillErrorCode.INVALID_FRONTMATTER,
            "Invalid SKILL.md frontmatter",
        )

    try:
        frontmatter = SkillFrontmatter.model_validate(parsed_yaml)
    except ValidationError as exc:
        errors = [_pydantic_error_to_skill_error(dict(e)) for e in exc.errors()]
        raise SkillValidationErrors(errors) from exc

    body = skill_markdown[match.end() :].strip()
    return ParsedSkillDocument(frontmatter=frontmatter, body=body)

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Read the chained PyYAML error — it gives the exact line and column of the syntax problem.
  2. Quote values containing special characters: `description: "Analyzes data: fast"`.
  3. Validate the block standalone: `python -c "import yaml,sys; yaml.safe_load(open('fm.yaml'))"` or any YAML linter.
  4. Replace tabs with spaces and fix indentation to consistent 2-space steps.

Example fix

# before (SKILL.md)
---
name: my-skill
description: Analyzes data: fast
---

# after
---
name: my-skill
description: "Analyzes data: fast"
---
Defensive patterns

Strategy: validation

Validate before calling

import yaml, re

_FRONTMATTER_RE = re.compile(r"\A---\s*\n(.*?)\n---\s*\n?", re.DOTALL)

def frontmatter_yaml_valid(md: str) -> bool:
    m = _FRONTMATTER_RE.match(md.lstrip("\ufeff"))
    if not m:
        return False
    try:
        yaml.safe_load(m.group(1))
        return True
    except yaml.YAMLError:
        return False

Try / catch

try:
    parsed = parse_skill_markdown(md)
except SkillDomainError as e:
    if e.code is SkillErrorCode.INVALID_FRONTMATTER and e.__cause__ is not None:
        show_author_yaml_error(e.__cause__)  # PyYAML line/col diagnostics
    raise

Prevention

When it happens

Trigger: A SKILL.md whose frontmatter contains YAML syntax errors — unbalanced quotes, a value with an unescaped ':' outside quotes, bad indentation, tabs used for indentation, or a stray duplicate key construct that PyYAML rejects.

Common situations: Descriptions containing colons written unquoted (`description: Analyzes data: fast`); copy-pasting rich text with tabs; mixing quote styles; multi-line values formatted incorrectly; editor auto-formatting breaking YAML.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/a94932b199607ff6. Report an issue: GitHub.