larksuite/cli · error
cannot inspect installed lark-suite: skill is not installed
Error message
cannot inspect installed lark-suite: skill is not installed
What it means
localOfficialSkills expects the 'lark-suite' skill to be installed whenever the previous skills state records suite layout and is readable. This error is thrown after scanning the entire installed-skills list without finding a skill named 'lark-suite' — the cached state says the suite layout should be present, but the actual global skills listing contains no such entry.
Source
Thrown at internal/skillscheck/sync.go:404
func localOfficialSkills(installed []installedSkill, previous *SkillsState, readable bool) ([]string, error) {
if !readable || previous == nil || EffectiveLayout(previous) == LayoutSeparate {
names := make([]string, 0, len(installed))
for _, skill := range installed {
names = append(names, skill.Name)
}
return names, nil
}
for _, skill := range installed {
if skill.Name != "lark-suite" {
continue
}
if skill.Path == "" {
return nil, fmt.Errorf("cannot inspect installed lark-suite: global skills JSON did not include its path")
}
return listDirectSubdirs(filepath.Join(skill.Path, "references"))
}
return nil, fmt.Errorf("cannot inspect installed lark-suite: skill is not installed")
}
func listDirectSubdirs(root string) ([]string, error) {
entries, err := vfs.ReadDir(root)
if err != nil {
return nil, err
}
names := []string{}
for _, entry := range entries {
if entry.IsDir() {
names = append(names, entry.Name())
}
}
sort.Strings(names)
return names, nil
}
func syncLayout(runner SkillsRunner, source string, layout Layout, plan SyncPlan, installed []installedSkill) error {View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Reinstall lark-suite globally so it appears in the global skills listing, then re-run sync.
- Delete the stale cached skills state so sync treats the layout as unknown and rebuilds it instead of requiring lark-suite.
- Ensure the same Node/npm global prefix is used for install and listing (check nvm/volta setup, `npm prefix -g`).
- Run the sync with force if supported so the state and installed set are reconciled from scratch.
Example fix
// before: stale suite-layout state with lark-suite uninstalled
// previous.Layout = "suite"; installed = [{Name: "foo", Path: "/x"}]
// localOfficialSkills(installed, previous, true) // -> "skill is not installed"
// after: reconcile state before inspecting
if !hasInstalledSkill(installed, "lark-suite") {
// treat as separate/unknown layout and rebuild from scratch
return namesFromInstalled(installed), nil
} Defensive patterns
Strategy: validation
Validate before calling
installed, err := listInstalledSkills(runner)
if err != nil { return err }
if readable && previous != nil && EffectiveLayout(previous) == LayoutSuite && !hasInstalledSkill(installed, "lark-suite") {
// state and reality disagree: clear state or reinstall the suite before sync
return fmt.Errorf("stale suite-layout state detected; lark-suite not installed")
} Type guard
func hasInstalledSkill(installed []installedSkill, name string) bool {
for _, s := range installed {
if s.Name == name { return true }
}
return false
} Try / catch
names, err := localOfficialSkills(installed, previous, readable)
if err != nil && strings.Contains(err.Error(), "skill is not installed") {
// reconcile: drop the stale suite state and proceed name-only
previous = nil
names, err = localOfficialSkills(installed, nil, false)
} Prevention
- Clear the skills state when uninstalling lark-suite manually, or reinstall it before syncing.
- Use one Node version manager so install and listing share the same global prefix.
- Run sync with force after major CLI upgrades to rebuild state/layout.
- Check `npm ls -g` for the suite package when suite-layout state exists.
When it happens
Trigger: Calling SyncSkills when the cached SkillsState indicates suite layout (readable, not separate), but ListGlobalSkillsJSON()/ListGlobalSkills() return a list that does not include 'lark-suite' — e.g. the suite was uninstalled, removed by another process, or the listing targets a different global prefix.
Common situations: The user ran `npm uninstall -g` on the suite package or pruned global packages; multiple Node version managers (nvm/volta) give different global prefixes so the listing checks the wrong location; a stale state file left behind after a failed uninstall; or a CLI version that renamed or dropped the suite skill.
Related errors
- cannot inspect installed lark-suite: global skills JSON did
- archive install failed: %s
- remove lark-suite failed: %s
- separate skills sync failed: %s
- annotated_csv did not parse into the rows the server reporte
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/4b2cae7d83a281cf.
Report an issue: GitHub.