{"record":{"id":"633ad01b9c6c00ec","repo":"conductor-oss/conductor","slug":"skill-md-is-missing-required-yaml-frontmatter","errorCode":null,"errorMessage":"SKILL.md is missing required YAML frontmatter","messagePattern":"SKILL\\.md is missing required YAML frontmatter","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java","lineNumber":567,"sourceCode":"            throws IOException {\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\n        byte[] buffer = new byte[8192];\n        long total = 0;\n        int read;\n        while ((read = in.read(buffer)) >= 0) {\n            total += read;\n            if (total > maxBytes) {\n                throw new IllegalArgumentException(errorMessage);\n            }\n            out.write(buffer, 0, read);\n        }\n        return out.toByteArray();\n    }\n\n    private Map<String, Object> parseSkillFrontmatter(String skillMd) {\n        Matcher matcher = FRONTMATTER_PATTERN.matcher(skillMd);\n        if (!matcher.matches()) {\n            throw new IllegalArgumentException(\"SKILL.md is missing required YAML frontmatter\");\n        }\n        try {\n            LoaderOptions options = new LoaderOptions();\n            Yaml yaml = new Yaml(new SafeConstructor(options));\n            Object value = yaml.load(matcher.group(1));\n            if (value == null) {\n                return Map.of();\n            }\n            if (!(value instanceof Map<?, ?> map)) {\n                throw new IllegalArgumentException(\"SKILL.md frontmatter must be a mapping\");\n            }\n            return MAPPER.convertValue(map, MAP_TYPE);\n        } catch (IllegalArgumentException e) {\n            throw e;\n        } catch (Exception e) {\n            throw new IllegalArgumentException(\n                    \"Invalid SKILL.md frontmatter: \" + e.getMessage(), e);\n        }","sourceCodeStart":549,"sourceCodeEnd":585,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/agentspan/src/main/java/org/conductoross/conductor/ai/agentspan/runtime/service/SkillRegistryService.java#L549-L585","documentation":"Thrown by parseSkillFrontmatter when SKILL.md does not begin with a YAML frontmatter block. The FRONTMATTER_PATTERN requires the file to start with '---' on its own line, then the YAML body, then a closing '---'. Without this block the skill name and parameters cannot be extracted, so parsing aborts before any field is read.","triggerScenarios":"POST /api/skills/register with a SKILL.md that starts with prose (e.g. '# My Skill') and has no leading '---' delimiters, or where the closing '---' is missing, or where leading whitespace/BOM precedes the first '---'.","commonSituations":"Authoring SKILL.md as plain markdown without frontmatter; a template that strips or misplaces the '---' fences; a UTF-8 BOM inserted by a Windows editor before the first '---'; an indented opening '---'.","solutions":["Add a YAML frontmatter block at the very top of SKILL.md: a line with exactly '---', the YAML (at least name:), then a closing '---', then the body.","Ensure the file starts at byte 0 with '---' — remove any BOM or leading blank lines.","Validate the SKILL.md locally with a YAML frontmatter parser before zipping."],"exampleFix":"---\nname: my-skill\ndescription: Does the thing.\n---\n# My Skill\n\nBody text here.","handlingStrategy":"validation","validationCode":"// Before zipping, verify SKILL.md has valid frontmatter\nString md = Files.readString(skillMdPath);\nif (!Pattern.compile(\"^---\\\\s*\\\\R.*?\\\\R---\\\\s*\\\\R?.*\", Pattern.DOTALL).matcher(md).matches()) {\n    throw new IllegalArgumentException(\"SKILL.md frontmatter missing\");\n}","typeGuard":"static boolean hasFrontmatter(String skillMd) {\n    return skillMd != null && skillMd.startsWith(\"---\") && skillMd.indexOf(\"---\", 3) > 3;\n}","tryCatchPattern":"try { skillRegistryService.register(manifest, pkg); }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"YAML frontmatter\")) { /* add --- block to SKILL.md, re-zip */ }\n    else throw e;\n}","preventionTips":["Start every SKILL.md with a '---' frontmatter fence containing at least name:.","Lint SKILL.md frontmatter in CI with a YAML parser before publishing."],"tags":["java","conductor","skill-registry","yaml","frontmatter","validation"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}