{"record":{"id":"ae6c47e30170b752","repo":"larksuite/cli","slug":"skills-state-is-unreadable","errorCode":null,"errorMessage":"skills state is unreadable","messagePattern":"skills state is unreadable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/skillscheck/state.go","lineNumber":22,"sourceCode":"package skillscheck\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/fs\"\n\t\"path/filepath\"\n\n\t\"github.com/larksuite/cli/internal/core\"\n\t\"github.com/larksuite/cli/internal/validate\"\n\t\"github.com/larksuite/cli/internal/vfs\"\n)\n\nconst (\n\tstateFile = \"skills-state.json\"\n)\n\nvar ErrUnreadableState = errors.New(\"skills state is unreadable\")\n\ntype SkillsState struct {\n\tVersion               string   `json:\"version\"`\n\tLayout                Layout   `json:\"layout,omitempty\"`\n\tOfficialSkills        []string `json:\"official_skills\"`\n\tOfficialSkillsUnknown bool     `json:\"official_skills_unknown,omitempty\"`\n\tUpdatedSkills         []string `json:\"updated_skills\"`\n\tAddedOfficialSkills   []string `json:\"added_official_skills\"`\n\tSkippedDeletedSkills  []string `json:\"skipped_deleted_skills\"`\n\tUpdatedAt             string   `json:\"updated_at\"`\n}\n\nfunc statePath() string {\n\treturn filepath.Join(core.GetBaseConfigDir(), stateFile)\n}\n\nfunc ReadState() (*SkillsState, bool, error) {\n\tdata, err := vfs.ReadFile(statePath())","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/skillscheck/state.go#L4-L40","documentation":"ErrUnreadableState is a sentinel error returned by ReadState in internal/skillscheck when the persisted skills-state.json file in the CLI config directory cannot be decoded as JSON, either as a generic object or as the SkillsState schema. It wraps the underlying json.Unmarshal error with %w so callers can match it with errors.Is. It signals a corrupt or schema-mismatched local state file, not an API problem.","triggerScenarios":"ReadState parses skills-state.json and json.Unmarshal fails: (1) the file is corrupt/truncated (interrupted write, disk issue) or contains invalid JSON; (2) the file parses as JSON but does not match SkillsState — e.g. a field like version or official_skills has the wrong JSON type (string vs array).","commonSituations":"Users hand-edit ~/.config/lark-cli/skills-state.json (or the platform config dir) and break the JSON; a crash or SIGKILL during WriteState left a partial file; an older or newer CLI version wrote a state schema whose field types changed, breaking unmarshal.","solutions":["Delete the corrupt skills-state.json file in the CLI base config directory (core.GetBaseConfigDir()) and rerun the command; ReadState treats a missing file as 'no state' and the state is regenerated.","Inspect the file with `cat <config-dir>/skills-state.json | jq .` to find the JSON syntax or type error and fix it manually.","Match the error with errors.Is(err, skillscheck.ErrUnreadableState) and fall back to defaults instead of aborting.","If corruption recurs, check disk health and ensure the CLI process is not being killed mid-write."],"exampleFix":"// before\nstate, found, err := skillscheck.ReadState()\nif err != nil { log.Fatal(err) }\n// after\nstate, found, err := skillscheck.ReadState()\nif errors.Is(err, skillscheck.ErrUnreadableState) {\n    // recover by ignoring corrupt state\n    state, found = nil, false\n} else if err != nil {\n    log.Fatal(err)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func stateExists(p string) bool { b, err := os.ReadFile(p); return err == nil && json.Valid(b) }","tryCatchPattern":"state, found, err := skillscheck.ReadState()\nif errors.Is(err, skillscheck.ErrUnreadableState) {\n    // corrupt state: proceed without it\n    state, found = nil, false\n} else if err != nil {\n    return err\n}","preventionTips":["Never hand-edit skills-state.json; let the CLI regenerate it","Delete the file instead of repairing it when the CLI reports unreadable state","Ensure the CLI is not killed mid-write (avoid SIGKILL during state updates)","Check disk health/filesystem errors if corruption recurs"],"tags":["json","state-corruption","cli","filesystem"],"backgroundTag":"corrupt-state-file","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"}