larksuite/cli · error
composed skill tree has an unsatisfied required skill
Error message
composed skill tree has an unsatisfied required skill
What it means
ErrUnsatisfiedSkillDependency reports that a skill retained in the final composed manifest declares a required skill that the composed tree does not retain. The resolver intentionally never widens Allow or overrides Remove to repair this: an incomplete distribution is treated as a build-integrity error and fails closed. The check runs in internal/skillpolicy/dependencies.go over composed.owner's requiredSkills.
Source
Thrown at internal/skillpolicy/resolver.go:50
var ErrMultipleSkillsOverlays = errors.New("multiple plugins customized skills; only one plugin may own skill content")
// ErrNoBaseSkillContent reports that Allow or Remove was requested against an
// empty base tree. This most often means an external wrapper main omitted
// cmd.SetEmbeddedSkillContent; exposing a sentinel lets the command layer give
// the integrator that specific recovery action instead of blaming a skill-name
// typo.
var ErrNoBaseSkillContent = errors.New("build embeds no base skill content")
// ErrInvalidHostBase reports that the wrapper-provided base skill tree is
// malformed. It is distinct from a plugin's replacement Base so diagnostics
// can direct the integrator to the correct owner.
var ErrInvalidHostBase = errors.New("host embedded skill content is invalid")
// ErrUnsatisfiedSkillDependency reports that a skill retained by the final
// composed manifest declares another skill that the manifest does not retain.
// The resolver never widens Allow or overrides Remove to repair this: an
// incomplete distribution is a build-integrity error.
var ErrUnsatisfiedSkillDependency = errors.New("composed skill tree has an unsatisfied required skill")
// Resolution is the build-local result of composing embedded skill assets.
// Content serves `skills list`/`read`; References projects canonical
// CLI-authored pointers onto that same tree.
type Resolution struct {
Content fs.FS
References *skillref.Resolver
}
// resolveContent is a test convenience over the production resolution path.
func resolveContent(base fs.FS, specs []PluginSkill) (fs.FS, error) {
resolved, err := ResolveWithReferences(base, specs)
if err != nil {
return nil, err
}
return resolved.Content, nil
}
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Read the wrapped error text to find which skill requires which missing dependency, then keep the dependency in the composed tree.
- Adjust the plugin's Allow list to include the required skill, or drop the Remove entry that deletes it.
- If a skill's requirement is wrong, fix the requiredSkills declaration in that skill's frontmatter so it no longer demands a skill you don't ship.
Example fix
// before
spec.Allow = []string{"skill-a"} // skill-a requires skill-b
// after
spec.Allow = []string{"skill-a", "skill-b"} Defensive patterns
Strategy: validation
Validate before calling
func checkDeps(retained, all map[string]Skill) error {
for name, s := range retained {
for _, dep := range s.RequiredSkills {
if _, ok := retained[dep]; !ok {
return fmt.Errorf("%s requires %s which is not retained", name, dep)
}
}
}
return nil
} Type guard
if errors.Is(err, skillpolicy.ErrUnsatisfiedSkillDependency) {
// read wrapped message for the missing dependency name
} Try / catch
if err := resolve(); err != nil {
if errors.Is(err, skillpolicy.ErrUnsatisfiedSkillDependency) {
// widen Allow or drop the offending Remove to include the dependency
}
} Prevention
- Before pruning an Allow list, check each candidate skill's requiredSkills in its frontmatter.
- Never Remove a skill without grepping the tree for skills that require it.
- Add resolver tests asserting dependency completeness for your plugin's overlay.
When it happens
Trigger: Removing a skill that another retained skill requires (Remove-based), allowing a subset that omits a dependency (Allow-based), or a plugin overlay replacement whose own Base omits a skill its retained skills require — each produce the wrapped sentinel with the missing dependency name.
Common situations: Plugin authors pruning 'unused' skills that are actually runtime dependencies; tightening an Allow list after a dependency was added upstream; UTF-8 BOM or naming changes making a dependency name mismatch (see TestResolve_UTF8BOMFrontmatterMissingRequiredSkillFailsClosed).
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- build embeds no base skill content
- host embedded skill content is invalid
- invalid skill reference remap
- Missing sheet_id for sheet {title!r}
- multiple plugins customized skills; only one plugin may own
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/b2757bed3483bfc8.
Report an issue: GitHub.