larksuite/cli · error
%s: skill %q is not in the base tree
Error message
%s: skill %q is not in the base tree
What it means
validateSkillsInBase verifies that every Allow/Remove skill name exists in the snapshotted base tree. Names must pass syntax checks first (validateSkillNames); this check is semantic — the skill simply is not present in the host base or plugin Base. The resolver never silently ignores missing names.
Source
Thrown at internal/skillpolicy/resolver.go:229
if err := validateSkillsInBase("Allow", spec.Allow, lower); err != nil {
return err
}
return validateSkillsInBase("Remove", spec.Remove, lower)
}
func validateSkillNames(field string, names []string) error {
for _, name := range names {
if !isSkillName(name) {
return fmt.Errorf("%s: %q is not a valid skill name", field, name)
}
}
return nil
}
func validateSkillsInBase(field string, names []string, base skillTreeSnapshot) error {
for _, name := range names {
if _, exists := base.skills[name]; !exists {
return fmt.Errorf("%s: skill %q is not in the base tree", field, name)
}
}
return nil
}
// skillExists reports whether fsys holds a skill named name -- a
// directory carrying SKILL.md, the shape internal/skillcontent treats as
// a skill.
func skillExists(fsys fs.FS, name string) (bool, error) {
if fsys == nil {
return false, nil
}
info, err := fs.Stat(fsys, name+"/SKILL.md")
switch {
case err == nil:
return !info.IsDir(), nil
case errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrInvalid):
return false, nilView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Run `lark-cli skills list` against the same build to see the actual base skill names, then correct the entry.
- If the skill is contributed by this plugin's Overlay, it does not need Allow — remove the entry.
- If the skill was renamed upstream, update the name in the plugin spec to the new identifier.
- Pre-validate by scanning the base FS (or snapshot) for the name before constructing the SkillsOverlay in tests.
Example fix
// before
spec.Remove = []string{"skills-managment"}
// after
spec.Remove = []string{"skills-management"} Defensive patterns
Strategy: validation
Validate before calling
names, err := collectBaseSkillNames(baseFS)
if err != nil { return err }
for _, n := range spec.Allow {
if !slices.Contains(names, n) { return fmt.Errorf("%q not in base tree", n) }
} Try / catch
if err != nil {
var candidates []string
return fmt.Errorf("unknown skill (run `lark-cli skills list`); did you mean one of %v?: %w", candidates, err)
} Prevention
- Copy skill names from the current build's `skills list`, not from memory or old docs
- Remember Allow/Remove reference base-tree skills, not skills your own Overlay adds
- Re-run dry-run tests after CLI upgrades that may rename skills
When it happens
Trigger: ResolveWithReferences with spec.Allow or spec.Remove naming a skill absent from lower.skills: a typo, a skill that only exists in the plugin's Overlay, or a skill removed/renamed in the CLI version being built against.
Common situations: Allow-listing a skill the plugin itself adds via Overlay (it must be in base, not the overlay, to be selectable); referencing a skill renamed upstream after a CLI upgrade; misspelling the skill directory name.
Related errors
- %s: skill %q is missing SKILL.md
- %s: skill %q has invalid metadata: %w
- %w; Allow/Remove require skills in the base tree
- Invalid column: {column!r}
- Invalid column index: {index}
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/12eab54bc527420b.
Report an issue: GitHub.