{"record":{"id":"f56f1f33ad0b570d","repo":"larksuite/cli","slug":"v0-2-index-contains-no-skills","errorCode":null,"errorMessage":"v0.2 index contains no skills","messagePattern":"v0\\.2 index contains no skills","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/skillscheck/sync.go","lineNumber":359,"sourceCode":"\t\t\tDetail: strings.Join(reasons, \"\\n\"),\n\t\t\tForce:  opts.Force,\n\t\t}\n\t}\n\n\treturn fallbackSeparate(opts, previous, readable, localOfficial, installed, fallbackPlan, reasons)\n}\n\nfunc fetchOfficialSkills(runner SkillsRunner, source string) ([]string, error) {\n\tresult := runner.FetchSkillsIndex(source)\n\tif result == nil || result.Err != nil {\n\t\treturn nil, fmt.Errorf(\"index request failed: %s\", resultDetail(result))\n\t}\n\tofficial, err := ParseOfficialSkillsIndexJSON(result.Stdout.String())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid v0.2 index: %w\", err)\n\t}\n\tif len(official) == 0 {\n\t\treturn nil, fmt.Errorf(\"v0.2 index contains no skills\")\n\t}\n\treturn official, nil\n}\n\nfunc listInstalledSkills(runner SkillsRunner) ([]installedSkill, error) {\n\tjsonResult := runner.ListGlobalSkillsJSON()\n\tif jsonResult != nil && jsonResult.Err == nil {\n\t\tif installed, err := parseInstalledSkillsJSON(jsonResult.Stdout.String()); err == nil {\n\t\t\treturn installed, nil\n\t\t}\n\t}\n\n\ttextResult := runner.ListGlobalSkills()\n\tif textResult != nil && textResult.Err == nil {\n\t\tnames := ParseSkillsList(textResult.Stdout.String())\n\t\tif names != nil {\n\t\t\tinstalled := make([]installedSkill, 0, len(names))\n\t\t\tfor _, name := range names {","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/skillscheck/sync.go#L341-L377","documentation":"fetchOfficialSkills returns this sentinel when the index parsed successfully as v0.2 JSON but the resulting official skills list is empty. An empty index cannot drive a sync plan, so the source is treated as failed and SyncSkills moves on to the next source. This is a server-side/content problem, not a client parsing problem.","triggerScenarios":"SyncSkills -> fetchOfficialSkills where ParseOfficialSkillsIndexJSON succeeds but returns a zero-length skills slice.","commonSituations":"The upstream publisher cleared or is repopulating the index; a staging/mirror source has an empty placeholder index; the wrong URL points at a valid-but-empty index document; CDN serving a stub during an outage.","solutions":["Verify the source URL points at the production index rather than a staging or placeholder document","Check with the index publisher/upstream whether the index is temporarily empty or being rebuilt","Try the next configured source in SkillsSources(); if all sources are empty, sync cannot proceed","If you control the source, republish the index with the full skills list","Inspect the fetched JSON yourself to confirm the skills array is truly empty"],"exampleFix":"// before: silent acceptance of empty index\n// after: warn and skip to next source\nif len(official) == 0 {\n    log.Printf(\"warning: %s served an empty skills index; trying next source\", source)\n    return nil, fmt.Errorf(\"v0.2 index contains no skills\")\n}","handlingStrategy":"fallback","validationCode":"body := result.Stdout.String()\nvar idx struct{ Skills []any `json:\"skills\"` }\nif json.Unmarshal([]byte(body), &idx) == nil && len(idx.Skills) == 0 {\n    return errors.New(\"index is valid but empty; skip this source\")\n}","typeGuard":null,"tryCatchPattern":"official, err := fetchOfficialSkills(runner, source)\nif err != nil && err.Error() == \"v0.2 index contains no skills\" {\n    // move to the next configured source rather than aborting\n    official, err = fetchOfficialSkills(runner, nextSource)\n}","preventionTips":["Point SkillsSources() at the production index, not staging/placeholder mirrors","Keep multiple sources configured so empty ones are skipped","Coordinate with the index publisher during repopulation windows","Spot-check the fetched JSON to distinguish empty content from wrong URL"],"tags":["go","skills-index","empty-response"],"backgroundTag":"empty-index-response","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"}