{"record":{"id":"459d58e50c352613","repo":"larksuite/cli","slug":"cannot-parse-skill-md-frontmatter-w","errorCode":null,"errorMessage":"cannot parse SKILL.md frontmatter: %w","messagePattern":"cannot parse SKILL\\.md frontmatter: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/skillpolicy/dependencies.go","lineNumber":73,"sourceCode":"\t\tif strings.TrimRight(line, \"\\r\") == \"---\" {\n\t\t\tclosed = true\n\t\t\tbreak\n\t\t}\n\t\tblock = append(block, line)\n\t}\n\tif !closed {\n\t\treturn nil, fmt.Errorf(\"SKILL.md frontmatter is not closed\")\n\t}\n\n\tvar frontmatter struct {\n\t\tMetadata struct {\n\t\t\tRequires struct {\n\t\t\t\tSkills []string `yaml:\"skills\"`\n\t\t\t} `yaml:\"requires\"`\n\t\t} `yaml:\"metadata\"`\n\t}\n\tif err := yaml.Unmarshal([]byte(strings.Join(block, \"\\n\")), &frontmatter); err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot parse SKILL.md frontmatter: %w\", err)\n\t}\n\n\trequired := frontmatter.Metadata.Requires.Skills\n\tseen := make(map[string]struct{}, len(required))\n\tout := make([]string, 0, len(required))\n\tfor _, dependency := range required {\n\t\tif !isSkillName(dependency) {\n\t\t\treturn nil, fmt.Errorf(\"required skill %q declared by %q is not a valid skill name\", dependency, skillName)\n\t\t}\n\t\tif _, duplicate := seen[dependency]; duplicate {\n\t\t\tcontinue\n\t\t}\n\t\tseen[dependency] = struct{}{}\n\t\tout = append(out, dependency)\n\t}\n\treturn out, nil\n}\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/skillpolicy/dependencies.go#L55-L91","documentation":"After collecting the frontmatter lines, parseRequiredSkills unmarshals them into a struct whose metadata.requires.skills is a []string, and wraps YAML errors as \"cannot parse SKILL.md frontmatter\". This means the block was delimited correctly but its content is not valid YAML or does not match the expected schema, so the skill's required-skills list cannot be extracted.","triggerScenarios":"yaml.Unmarshal on the joined frontmatter fails: invalid YAML syntax (bad indentation, tabs, unquoted special characters), or the keys are shaped differently than metadata.requires.skills (e.g. requires as a string, or skills as a map).","commonSituations":"Indentation with tabs instead of spaces in hand-edited frontmatter; `requires: foo` written as a scalar instead of a nested skills list; unquoted values containing `:` or `#`; YAML anchors/tags unsupported by the parser.","solutions":["Fix the YAML so it parses: spaces (not tabs), correct nesting under metadata.requires.skills","Ensure skills is a list of strings: skills: [skill-a, skill-b]","Quote values containing special YAML characters","Validate frontmatter with a YAML parser or the repo's skill-format check before committing"],"exampleFix":"// before (tabs break YAML)\nmetadata:\n\trequires:\n\t\tskills: foo\n// after\nmetadata:\n  requires:\n    skills:\n      - foo","handlingStrategy":"validation","validationCode":"fm := extractFrontmatter(skillMD) // lines between the two ---\nvar probe struct {\n    Metadata struct {\n        Requires struct {\n            Skills []string `yaml:\"skills\"`\n        } `yaml:\"requires\"`\n    } `yaml:\"metadata\"`\n}\nif err := yaml.Unmarshal([]byte(fm), &probe); err != nil {\n    return fmt.Errorf(\"invalid frontmatter YAML in SKILL.md: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := parseRequiredSkills(name, data); err != nil {\n    var yerr *yaml.TypeError\n    if errors.As(err, &yerr) || strings.Contains(err.Error(), \"cannot parse SKILL.md frontmatter\") {\n        return fmt.Errorf(\"skill %s: fix frontmatter to metadata.requires.skills (list of strings)\", name)\n    }\n    return err\n}","preventionTips":["Use spaces, never tabs, in YAML frontmatter","Model requires as: metadata.requires.skills: [list-of-names]","Quote strings containing : or # characters","Validate frontmatter YAML in CI before publishing skills"],"tags":["skillpolicy","yaml","frontmatter","schema"],"backgroundTag":"frontmatter-parse-failed","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}