larksuite/cli · error
cannot inspect installed lark-suite: global skills JSON did
Error message
cannot inspect installed lark-suite: global skills JSON did not include its path
What it means
localOfficialSkills builds the list of locally-installed official skills. When the previous state indicates suite layout, it locates the installed 'lark-suite' entry in the global skills JSON and inspects its references directory. This error is thrown when a 'lark-suite' entry exists but its Path field is empty, meaning the listing did not include install-location metadata, so the tool cannot determine where the suite is installed to enumerate its references.
Source
Thrown at internal/skillscheck/sync.go:400
}
return nil, fmt.Errorf("local skills list failed")
}
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)View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Reinstall lark-suite globally so the host CLI produces a fresh listing including the install path, then re-run sync.
- Clear the cached skills state so localOfficialSkills takes the name-only branch instead of requiring the path.
- Upgrade the host CLI so its global skills JSON format includes path metadata for every installed skill.
- Inspect the global skills JSON (`lark skills list --json` or equivalent) to confirm the lark-suite entry includes a path; if not, report or fix the CLI version emitting it.
Example fix
// before: name-only installed list used in suite layout
// installed := [{Name: "lark-suite", Path: ""}]
// names, err := localOfficialSkills(installed, previous, true) // -> error
// after: degrade gracefully when path metadata is absent
if skill.Path == "" {
// fall back to name-only enumeration instead of failing
return namesFromInstalled(installed), nil
}
return listDirectSubdirs(filepath.Join(skill.Path, "references")) Defensive patterns
Strategy: validation
Validate before calling
installed, err := listInstalledSkills(runner)
if err != nil { return err }
if readable && previous != nil && EffectiveLayout(previous) != LayoutSeparate {
suite, ok := findSkill(installed, "lark-suite")
if !ok {
return fmt.Errorf("state says suite layout but lark-suite is not installed")
}
if suite.Path == "" {
// listing lacks path metadata; refresh listing JSON or clear state first
return fmt.Errorf("global skills listing lacks path for lark-suite")
}
} Type guard
func hasInstallPath(s installedSkill) bool { return s.Path != "" }
func findSkill(installed []installedSkill, name string) (installedSkill, bool) {
for _, s := range installed {
if s.Name == name { return s, true }
}
return installedSkill{}, false
} Try / catch
names, err := localOfficialSkills(installed, previous, readable)
if err != nil {
if strings.Contains(err.Error(), "global skills JSON did not include its path") {
// degrade to name-only enumeration and let sync rebuild the state
names = namesFromInstalled(installed)
} else {
return err
}
} Prevention
- Keep the host CLI current so its global skills JSON always emits path metadata.
- Refresh the cached skills state after any manual npm global install/uninstall.
- Verify `lark skills list --json` output includes paths before running sync in suite layout.
- Avoid hand-editing global skills JSON or the skills state file.
When it happens
Trigger: Calling SyncSkills (via localOfficialSkills) when the previous skills state reports suite layout, the global skills listing was parsed successfully and contains a 'lark-suite' entry, but that entry has an empty Path — typically because the listing only carries skill names (e.g. derived from the text fallback in listInstalledSkills, which builds installedSkill{Name: name} without a path).
Common situations: The host CLI's JSON listing failed so the code fell back to the name-only text listing; an older CLI version emits JSON without path fields; the global skills JSON was hand-edited or corrupted; or the state file says suite layout while the listing format changed between CLI versions.
Related errors
- cannot inspect installed lark-suite: skill is not installed
- 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/286825819f462661.
Report an issue: GitHub.