larksuite/cli · error

cannot parse SKILL.md frontmatter: %w

Error message

cannot parse SKILL.md frontmatter: %w

What it means

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.

Source

Thrown at internal/skillpolicy/dependencies.go:73

		if strings.TrimRight(line, "\r") == "---" {
			closed = true
			break
		}
		block = append(block, line)
	}
	if !closed {
		return nil, fmt.Errorf("SKILL.md frontmatter is not closed")
	}

	var frontmatter struct {
		Metadata struct {
			Requires struct {
				Skills []string `yaml:"skills"`
			} `yaml:"requires"`
		} `yaml:"metadata"`
	}
	if err := yaml.Unmarshal([]byte(strings.Join(block, "\n")), &frontmatter); err != nil {
		return nil, fmt.Errorf("cannot parse SKILL.md frontmatter: %w", err)
	}

	required := frontmatter.Metadata.Requires.Skills
	seen := make(map[string]struct{}, len(required))
	out := make([]string, 0, len(required))
	for _, dependency := range required {
		if !isSkillName(dependency) {
			return nil, fmt.Errorf("required skill %q declared by %q is not a valid skill name", dependency, skillName)
		}
		if _, duplicate := seen[dependency]; duplicate {
			continue
		}
		seen[dependency] = struct{}{}
		out = append(out, dependency)
	}
	return out, nil
}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Fix the YAML so it parses: spaces (not tabs), correct nesting under metadata.requires.skills
  2. Ensure skills is a list of strings: skills: [skill-a, skill-b]
  3. Quote values containing special YAML characters
  4. Validate frontmatter with a YAML parser or the repo's skill-format check before committing

Example fix

// before (tabs break YAML)
metadata:
	requires:
		skills: foo
// after
metadata:
  requires:
    skills:
      - foo
Defensive patterns

Strategy: validation

Validate before calling

fm := extractFrontmatter(skillMD) // lines between the two ---
var probe struct {
    Metadata struct {
        Requires struct {
            Skills []string `yaml:"skills"`
        } `yaml:"requires"`
    } `yaml:"metadata"`
}
if err := yaml.Unmarshal([]byte(fm), &probe); err != nil {
    return fmt.Errorf("invalid frontmatter YAML in SKILL.md: %w", err)
}

Try / catch

if _, err := parseRequiredSkills(name, data); err != nil {
    var yerr *yaml.TypeError
    if errors.As(err, &yerr) || strings.Contains(err.Error(), "cannot parse SKILL.md frontmatter") {
        return fmt.Errorf("skill %s: fix frontmatter to metadata.requires.skills (list of strings)", name)
    }
    return err
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04). Data as JSON: /api/errors/459d58e50c352613. Report an issue: GitHub.