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

  1. Reinstall lark-suite globally so it appears in the global skills listing, then re-run sync.
  2. Delete the stale cached skills state so sync treats the layout as unknown and rebuilds it instead of requiring lark-suite.
  3. Ensure the same Node/npm global prefix is used for install and listing (check nvm/volta setup, `npm prefix -g`).
  4. 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

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


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