larksuite/cli · error

skills synced but state not written: %w

Error message

skills synced but state not written: %w

What it means

finishSync in internal/skillscheck/sync.go returns this error when skills were successfully downloaded/installed but persisting the resulting SkillsState via WriteState failed. The CLI reports Action 'failed' even though the on-disk skills are current, because the recorded state (layout, versions, timestamps) could not be written. This causes redundant re-syncs on the next run since state tracking is lost.

Source

Thrown at internal/skillscheck/sync.go:513

		Added:           plan.Added,
		SkippedDeleted:  plan.SkippedDeleted,
		Warning:         warning,
		Layout:          layout,
		Force:           opts.Force,
	}
	state := SkillsState{
		Version:               opts.Version,
		Layout:                layout,
		OfficialSkills:        plan.OfficialSkills,
		OfficialSkillsUnknown: officialUnknown,
		UpdatedSkills:         plan.ToUpdate,
		AddedOfficialSkills:   plan.Added,
		SkippedDeletedSkills:  plan.SkippedDeleted,
		UpdatedAt:             opts.Now().UTC().Format(time.RFC3339),
	}
	if err := WriteState(state); err != nil {
		result.Action = "failed"
		result.Err = fmt.Errorf("skills synced but state not written: %w", err)
	}
	return result
}

func hasInstalledSkill(installed []installedSkill, name string) bool {
	for _, skill := range installed {
		if skill.Name == name {
			return true
		}
	}
	return false
}

func resultDetail(result *selfupdate.NpmResult) string {
	if result == nil {
		return ""
	}
	parts := []string{}

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Check disk space (df -h) and free space if full
  2. Fix ownership/permissions of the state file and its directory (ls -la on the config dir; chown back to your user)
  3. Verify the config/state directory is writable (touch a test file in it)
  4. Delete the corrupted state file and re-run the sync so it is regenerated

Example fix

// before
WriteState(state) -> error: open ~/.lark-cli/skills_state.json: permission denied

// after
sudo chown -R $(whoami) ~/.lark-cli
lark-cli skills sync  # state writes succeed
Defensive patterns

Strategy: validation

Validate before calling

// verify state dir is writable before syncing
stateDir := os.Getenv("LARKSUITE_CLI_CONFIG_DIR")
if stateDir == "" {
    home, _ := os.UserHomeDir()
    stateDir = filepath.Join(home, ".lark-cli")
}
test := filepath.Join(stateDir, ".write-test")
if err := os.WriteFile(test, nil, 0o600); err != nil {
    return fmt.Errorf("state dir not writable: %w", err)
}
os.Remove(test)

Try / catch

res := syncSkills(ctx)
if res.Action == "failed" && strings.Contains(res.Err.Error(), "state not written") {
    // skills are current; only state persistence failed
    log.Printf("re-syncing needed later: %v", res.Err)
    if errors.Is(res.Err, os.ErrPermission) { /* fix ownership of ~/.lark-cli */ }
}

Prevention

When it happens

Trigger: SyncSkills or fallbackSeparate reaching finishSync after a successful plan/install, and WriteState(state) returning a non-nil error while persisting the skills state file.

Common situations: Disk full or quota exceeded; the CLI config/state directory is read-only or owned by another user (e.g. ran with sudo once, now ~/.lark-cli files are root-owned); antivirus or backup software locks the state file; a corrupted state file prevents rewriting; container with a read-only home volume.

Related errors


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