larksuite/cli · error
%s: skill %q has invalid metadata: %w
Error message
%s: skill %q has invalid metadata: %w
What it means
scanSkillTree calls readSkillManifest to parse each skill's SKILL.md frontmatter. If parsing or validation fails, composition aborts with this error, labeled by which tree (host base, plugin Base, plugin Overlay) held the bad manifest. It keeps malformed skill metadata out of the composed tree used by skills list/read and --help pointers.
Source
Thrown at internal/skillpolicy/resolver.go:192
}
for _, e := range entries {
name := e.Name()
if !e.IsDir() {
return snapshot, fmt.Errorf("%s: %q is not a directory; every %s entry must be a <skill>/ dir", label, name, label)
}
if !isSkillName(name) {
return snapshot, fmt.Errorf("%s: %q is not a valid skill name", label, name)
}
ok, err := skillExists(source, name)
if err != nil {
return snapshot, fmt.Errorf("%s: probing skill %q: %w", label, name, err)
}
if !ok {
return snapshot, fmt.Errorf("%s: skill %q is missing SKILL.md", label, name)
}
manifest, err := readSkillManifest(source, name)
if err != nil {
return snapshot, fmt.Errorf("%s: skill %q has invalid metadata: %w", label, name, err)
}
snapshot.skills[name] = manifest
}
return snapshot, nil
}
// validateSelection rejects allow/remove entries that cannot compose against
// the already-validated base snapshot.
func validateSelection(lower skillTreeSnapshot, spec *platform.SkillsOverlay) error {
if err := validateSkillNames("Allow", spec.Allow); err != nil {
return err
}
if err := validateSkillNames("Remove", spec.Remove); err != nil {
return err
}
if len(lower.skills) == 0 && (len(spec.Allow) > 0 || len(spec.Remove) > 0) {
return fmt.Errorf("%w; Allow/Remove require skills in the base tree", ErrNoBaseSkillContent)
}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Fix the SKILL.md frontmatter for the named skill; validate with the CLI's schema/format checks.
- Run the skill format check (node scripts/skill-format-check/index.js) on the offending skill before rebuilding.
- If the plugin is third-party, pin/upgrade the plugin to a version whose manifests match the host CLI.
- Diff the manifest against a known-good shipped skill to spot missing or mistyped frontmatter fields.
Defensive patterns
Strategy: validation
Validate before calling
for _, name := range skillNames {
if err := validateManifest(fsys, name); err != nil {
return fmt.Errorf("skill %s has invalid metadata: %w", name, err)
}
} Try / catch
if _, err := skillpolicy.ResolveWithReferences(base, specs); err != nil {
var wrapped interface{ Unwrap() error }
// log full chain; fix the SKILL.md frontmatter identified by the label
return fmt.Errorf("skill tree invalid: %w", err)
} Prevention
- Keep SKILL.md frontmatter in the canonical format of a recently shipped skill and diff before publishing
- Run scripts/skill-format-check in CI for every skill change
- Bump and re-validate plugin manifests after CLI manifest-format upgrades
When it happens
Trigger: ResolveWithReferences encounters a SKILL.md whose frontmatter is unparseable or fails manifest validation (missing/invalid required fields), for any skill in the base or overlay FS.
Common situations: Hand-edited frontmatter with broken YAML; missing required description field; a skill shipped by a plugin with an older manifest format than the host expects.
Related errors
- host embedded skill content is invalid
- %s: skill %q is missing SKILL.md
- %w; Allow/Remove require skills in the base tree
- %s: skill %q is not in the base tree
- Invalid column: {column!r}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/3c19b39ec51a3768.
Report an issue: GitHub.