larksuite/cli · error

skill %s is not a complete v0.2 archive entry

Error message

skill %s is not a complete v0.2 archive entry

What it means

ParseOfficialSkillsIndexJSON requires every skill entry to be a complete v0.2 archive entry: type must be "archive", URL non-empty, and digest matching digestPattern. Any entry failing these checks aborts the whole index parse with this error.

Source

Thrown at internal/skillscheck/sync.go:117

		Digest string `json:"digest"`
	}
	type officialIndex struct {
		Skills []officialSkill `json:"skills"`
	}

	var index officialIndex
	if err := json.Unmarshal([]byte(text), &index); err != nil {
		return nil, err
	}

	seen := map[string]bool{}
	for _, skill := range index.Skills {
		candidate := strings.TrimSpace(skill.Name)
		if !skillNamePattern.MatchString(candidate) {
			return nil, fmt.Errorf("invalid skill name %q", candidate)
		}
		if skill.Type != "archive" || strings.TrimSpace(skill.URL) == "" || !digestPattern.MatchString(skill.Digest) {
			return nil, fmt.Errorf("skill %s is not a complete v0.2 archive entry", candidate)
		}
		if seen[candidate] {
			return nil, fmt.Errorf("duplicate skill %s", candidate)
		}
		seen[candidate] = true
	}

	return sortedKeys(seen), nil
}

// parseGlobalSkillsList parses the output of "npx -y skills ls -g"
func parseGlobalSkillsList(lines []string) []string {
	seen := map[string]bool{}

	for _, line := range lines {
		trimmed := strings.TrimSpace(line)

		// Skip header

View on GitHub (pinned to 7fd6ef3c07)

Solutions

  1. Ensure each entry has `type: "archive"`, a non-empty `url`, and a valid digest (e.g. sha256:<64 hex chars>)
  2. Check the index format version; upgrade the CLI if the upstream index moved past v0.2
  3. Verify the index source URL is the official one, not a partial cache or mirror
  4. Regenerate the index with all required archive fields populated

Example fix

// before
{"name": "crm-sync", "type": "directory", "url": "", "digest": "abc123"}
// after
{"name": "crm-sync", "type": "archive", "url": "https://.../crm-sync.tgz", "digest": "sha256:<64 hex chars>"}
Defensive patterns

Strategy: validation

Validate before calling

var idx struct{ Skills []struct{ Type, URL, Digest string } `json:"skills"` } `json:"skills"`
if err := json.Unmarshal(indexData, &idx); err == nil {
    for _, s := range idx.Skills {
        if s.Type != "archive" || strings.TrimSpace(s.URL) == "" || len(s.Digest) < 64 {
            // entry is not a complete v0.2 archive entry; fix before parsing
        }
    }
}

Try / catch

skills, err := skillscheck.ParseOfficialSkillsIndexJSON(data)
if err != nil {
    if strings.Contains(err.Error(), "not a complete v0.2 archive entry") {
        // log which index version/source was used; refresh or downgrade index
    }
    return err
}

Prevention

When it happens

Trigger: fetchOfficialSkills parsing an index where a skill entry has type != "archive", an empty/whitespace URL, or a digest not matching digestPattern (e.g. missing sha256 hex hash).

Common situations: Upstream index lists a non-archive entry type (e.g. "directory" or new format the CLI doesn't support); a mirrored/truncated index lost URL or digest fields; a newer index schema version with different field semantics than the parser's v0.2 expectations.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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