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

  1. Fix the SKILL.md frontmatter for the named skill; validate with the CLI's schema/format checks.
  2. Run the skill format check (node scripts/skill-format-check/index.js) on the offending skill before rebuilding.
  3. If the plugin is third-party, pin/upgrade the plugin to a version whose manifests match the host CLI.
  4. 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

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


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