{"record":{"id":"4b2cae7d83a281cf","repo":"larksuite/cli","slug":"cannot-inspect-installed-lark-suite-skill-is-not","errorCode":null,"errorMessage":"cannot inspect installed lark-suite: skill is not installed","messagePattern":"cannot inspect installed lark-suite: skill is not installed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/skillscheck/sync.go","lineNumber":404,"sourceCode":"func localOfficialSkills(installed []installedSkill, previous *SkillsState, readable bool) ([]string, error) {\n\tif !readable || previous == nil || EffectiveLayout(previous) == LayoutSeparate {\n\t\tnames := make([]string, 0, len(installed))\n\t\tfor _, skill := range installed {\n\t\t\tnames = append(names, skill.Name)\n\t\t}\n\t\treturn names, nil\n\t}\n\n\tfor _, skill := range installed {\n\t\tif skill.Name != \"lark-suite\" {\n\t\t\tcontinue\n\t\t}\n\t\tif skill.Path == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"cannot inspect installed lark-suite: global skills JSON did not include its path\")\n\t\t}\n\t\treturn listDirectSubdirs(filepath.Join(skill.Path, \"references\"))\n\t}\n\treturn nil, fmt.Errorf(\"cannot inspect installed lark-suite: skill is not installed\")\n}\n\nfunc listDirectSubdirs(root string) ([]string, error) {\n\tentries, err := vfs.ReadDir(root)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnames := []string{}\n\tfor _, entry := range entries {\n\t\tif entry.IsDir() {\n\t\t\tnames = append(names, entry.Name())\n\t\t}\n\t}\n\tsort.Strings(names)\n\treturn names, nil\n}\n\nfunc syncLayout(runner SkillsRunner, source string, layout Layout, plan SyncPlan, installed []installedSkill) error {","sourceCodeStart":386,"sourceCodeEnd":422,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/skillscheck/sync.go#L386-L422","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: stale suite-layout state with lark-suite uninstalled\n//   previous.Layout = \"suite\"; installed = [{Name: \"foo\", Path: \"/x\"}]\n//   localOfficialSkills(installed, previous, true) // -> \"skill is not installed\"\n// after: reconcile state before inspecting\nif !hasInstalledSkill(installed, \"lark-suite\") {\n    // treat as separate/unknown layout and rebuild from scratch\n    return namesFromInstalled(installed), nil\n}","handlingStrategy":"validation","validationCode":"installed, err := listInstalledSkills(runner)\nif err != nil { return err }\nif readable && previous != nil && EffectiveLayout(previous) == LayoutSuite && !hasInstalledSkill(installed, \"lark-suite\") {\n    // state and reality disagree: clear state or reinstall the suite before sync\n    return fmt.Errorf(\"stale suite-layout state detected; lark-suite not installed\")\n}","typeGuard":"func hasInstalledSkill(installed []installedSkill, name string) bool {\n    for _, s := range installed {\n        if s.Name == name { return true }\n    }\n    return false\n}","tryCatchPattern":"names, err := localOfficialSkills(installed, previous, readable)\nif err != nil && strings.Contains(err.Error(), \"skill is not installed\") {\n    // reconcile: drop the stale suite state and proceed name-only\n    previous = nil\n    names, err = localOfficialSkills(installed, nil, false)\n}","preventionTips":["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."],"tags":["skills-sync","npm","suite-layout","stale-state"],"backgroundTag":"skill-not-installed","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}