larksuite/cli · error
remove lark-suite failed: %s
Error message
remove lark-suite failed: %s
What it means
syncLayout's archive path, after installing individual skills, removes the legacy 'lark-suite' wrapper skill when it is still installed (migrating from suite to separate layout). This error is returned when runner.RemoveGlobalSkills(["lark-suite"]) returns nil or a result with Err set — i.e. the npm global uninstall of the suite package failed.
Source
Thrown at internal/skillscheck/sync.go:434
}
}
sort.Strings(names)
return names, nil
}
func syncLayout(runner SkillsRunner, source string, layout Layout, plan SyncPlan, installed []installedSkill) error {
if layout == LayoutSuite {
return syncSuite(runner, source, plan, installed)
}
if len(plan.ToUpdate) > 0 {
result := runner.InstallSkills(source, plan.ToUpdate)
if result == nil || result.Err != nil {
return fmt.Errorf("archive install failed: %s", resultDetail(result))
}
}
if hasInstalledSkill(installed, "lark-suite") {
if result := runner.RemoveGlobalSkills([]string{"lark-suite"}); result == nil || result.Err != nil {
return fmt.Errorf("remove lark-suite failed: %s", resultDetail(result))
}
}
return nil
}
func fallbackSeparate(opts SyncOptions, previous *SkillsState, readable bool, local []string, installed []installedSkill, plan *SyncPlan, reasons []string) *SyncResult {
if plan == nil && readable && previous != nil && len(previous.OfficialSkills) > 0 {
fallback := PlanSync(SyncInput{
Version: opts.Version,
OfficialSkills: previous.OfficialSkills,
LocalSkills: local,
PreviousState: previous,
StateReadable: true,
Force: opts.Force,
})
plan = &fallback
}
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Inspect the %s detail in the message for the exact npm uninstall error, then fix it (usually permissions or a changed global prefix).
- Run the removal manually (`npm uninstall -g <suite-package>`) with the same npm/prefix the CLI uses, then re-run sync.
- Fix global-prefix permissions (chown the prefix or use a user-owned nvm prefix) before retrying.
- If the suite directory was manually removed, reinstall it once so npm can cleanly uninstall it.
Example fix
// before: npm uninstall fails with EACCES
if result := runner.RemoveGlobalSkills([]string{"lark-suite"}); result == nil || result.Err != nil {
return fmt.Errorf("remove lark-suite failed: %s", resultDetail(result))
}
// after: ensure a writable, consistent global prefix first
// npm config set prefix ~/.npm-global (and add to PATH)
// then retry the sync so RemoveGlobalSkills succeeds Defensive patterns
Strategy: validation
Validate before calling
// before removal: confirm npm can see and remove the package
suite, _ := findSkill(installed, "lark-suite")
if suite.Path != "" {
if _, err := os.Stat(suite.Path); err != nil {
// package dir missing -> npm uninstall will fail; repair first
}
}
// also confirm the npm global prefix is writable before attempting removal Type guard
func removalOK(r *selfupdate.NpmResult) bool { return r != nil && r.Err == nil } Try / catch
if result := runner.RemoveGlobalSkills([]string{"lark-suite"}); result == nil || result.Err != nil {
// retry once after repairing npm state, e.g. `npm uninstall -g <suite>` manually
if retry := runner.RemoveGlobalSkills([]string{"lark-suite"}); retry != nil && retry.Err == nil {
return nil
}
return fmt.Errorf("remove lark-suite failed: %s", resultDetail(result))
} Prevention
- Use a user-owned npm global prefix (nvm) to avoid EACCES on uninstall.
- Do not manually delete global package directories; use npm uninstall.
- Keep the same npm/prefix for install, listing, and removal within one sync run.
- Inspect the npm error detail before retrying to address the root cause (permissions vs missing package).
When it happens
Trigger: Calling SyncSkills with archive layout when hasInstalledSkill(installed, "lark-suite") is true and runner.RemoveGlobalSkills fails — e.g. the npm uninstall exits non-zero due to permissions, the package was modified externally, or npm is not on PATH.
Common situations: Global prefix owned by root or another user (EACCES); nvm prefix switched between install and removal so the package is 'missing' to npm; the package directory was manually deleted leaving npm metadata inconsistent; concurrent package managers (pnpm/yarn global) claiming the package.
Related errors
- cannot inspect installed lark-suite: global skills JSON did
- cannot inspect installed lark-suite: skill is not installed
- archive install 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/7ae4b107d4f8a8f1.
Report an issue: GitHub.