{"record":{"id":"a94932b199607ff6","repo":"zylon-ai/private-gpt","slug":"invalid-frontmatter","errorCode":"INVALID_FRONTMATTER","errorMessage":"The SKILL.md frontmatter is not valid YAML.","messagePattern":"The SKILL\\.md frontmatter is not valid YAML\\.","errorType":"exception","errorClass":"SkillDomainError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/skills/parser.py","lineNumber":87,"sourceCode":"\nclass ParsedSkillDocument(BaseModel):\n    frontmatter: SkillFrontmatter\n    body: str = Field(default=\"\")\n\n\ndef parse_skill_markdown(skill_markdown: str) -> ParsedSkillDocument:\n    match = _FRONTMATTER_RE.match(skill_markdown)\n    if not match:\n        raise SkillDomainError(\n            SkillErrorCode.MISSING_FRONTMATTER,\n            \"SKILL.md must start with YAML frontmatter\",\n        )\n\n    raw_frontmatter = match.group(1)\n    try:\n        parsed_yaml = yaml.safe_load(raw_frontmatter)\n    except yaml.YAMLError as e:\n        raise SkillDomainError(\n            SkillErrorCode.INVALID_FRONTMATTER,\n            \"The SKILL.md frontmatter is not valid YAML.\",\n        ) from e\n    if not isinstance(parsed_yaml, dict):\n        raise SkillDomainError(\n            SkillErrorCode.INVALID_FRONTMATTER,\n            \"Invalid SKILL.md frontmatter\",\n        )\n\n    try:\n        frontmatter = SkillFrontmatter.model_validate(parsed_yaml)\n    except ValidationError as exc:\n        errors = [_pydantic_error_to_skill_error(dict(e)) for e in exc.errors()]\n        raise SkillValidationErrors(errors) from exc\n\n    body = skill_markdown[match.end() :].strip()\n    return ParsedSkillDocument(frontmatter=frontmatter, body=body)\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/skills/parser.py#L69-L105","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the chained PyYAML error — it gives the exact line and column of the syntax problem.","Quote values containing special characters: `description: \"Analyzes data: fast\"`.","Validate the block standalone: `python -c \"import yaml,sys; yaml.safe_load(open('fm.yaml'))\"` or any YAML linter.","Replace tabs with spaces and fix indentation to consistent 2-space steps."],"exampleFix":"# before (SKILL.md)\n---\nname: my-skill\ndescription: Analyzes data: fast\n---\n\n# after\n---\nname: my-skill\ndescription: \"Analyzes data: fast\"\n---","handlingStrategy":"validation","validationCode":"import yaml, re\n\n_FRONTMATTER_RE = re.compile(r\"\\A---\\s*\\n(.*?)\\n---\\s*\\n?\", re.DOTALL)\n\ndef frontmatter_yaml_valid(md: str) -> bool:\n    m = _FRONTMATTER_RE.match(md.lstrip(\"\\ufeff\"))\n    if not m:\n        return False\n    try:\n        yaml.safe_load(m.group(1))\n        return True\n    except yaml.YAMLError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    parsed = parse_skill_markdown(md)\nexcept SkillDomainError as e:\n    if e.code is SkillErrorCode.INVALID_FRONTMATTER and e.__cause__ is not None:\n        show_author_yaml_error(e.__cause__)  # PyYAML line/col diagnostics\n    raise","preventionTips":["Always quote frontmatter values containing colons or special characters.","Use spaces, never tabs, for YAML indentation.","Run a YAML linter on frontmatter in the skill authoring pipeline/CI."],"tags":["skills","yaml","frontmatter","parsing","syntax"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}