larksuite/cli · error

required skill %q declared by %q is not a valid skill name

Error message

required skill %q declared by %q is not a valid skill name

What it means

Each entry in metadata.requires.skills must pass isSkillName; parseRequiredSkills throws "required skill %q declared by %q is not a valid skill name" for entries violating the skill-name rules. This keeps dependency references resolvable and unambiguous within the composed skill tree.

Source

Thrown at internal/skillpolicy/dependencies.go:81

	}

	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
}

// validateRequiredSkills checks the already-composed owner manifest. It must
// run after Base -> Allow -> Remove -> Overlay so no validation branch can
// accidentally disagree with the tree that list/read actually serves.
func validateRequiredSkills(composed *overlayFS) error {
	if composed == nil {
		return nil
	}
	names := make([]string, 0, len(composed.owner))

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Rename the dependency to a valid skill name (lowercase kebab-case, no slashes or spaces)
  2. Match the dependency string exactly to the target skill directory's name
  3. Trim stray whitespace/quotes from the list entries
  4. Check the referenced skill's actual name via its SKILL.md or the skill registry

Example fix

// before
skills: [deployment/Skill-A, My Skill]
// after
skills: [deployment-skill-a]
Defensive patterns

Strategy: validation

Validate before calling

var validSkillName = regexp.MustCompile(`^[a-z0-9]+(-[a-z0-9]+)*$`)
for _, dep := range requiredSkills {
    if !validSkillName.MatchString(dep) {
        return fmt.Errorf("invalid required skill name %q; use lowercase kebab-case", dep)
    }
}

Try / catch

if _, err := parseRequiredSkills(name, data); err != nil {
    if strings.Contains(err.Error(), "is not a valid skill name") {
        return fmt.Errorf("skill %s: rename dependencies to valid skill names (lowercase, no slashes/spaces)", name)
    }
    return err
}

Prevention

When it happens

Trigger: A skills list entry fails isSkillName — e.g. it contains a slash/path ("skills/foo"), uppercase letters, spaces, empty string, or other characters outside the allowed skill-name character set.

Common situations: Writing a filesystem path or URL instead of the skill name; casing mistakes like "My-Skill"; stray quotes, commas, or trailing whitespace inside YAML flow lists; referencing a skill by its display title rather than its name.

Related errors


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