siyuan-note/siyuan · error
no SKILL.md found in the archive
Error message
no SKILL.md found in the archive
What it means
Thrown by installFromZip after a successful unzip when findSkillDirs finds no directory containing SKILL.md. The recursive search honors wrapper directories and a skills/<name> layout, but if no SKILL.md exists anywhere it gives up.
Source
Thrown at kernel/util/skill.go:445
}
defer os.RemoveAll(tmpRoot)
zipPath := filepath.Join(tmpRoot, "src.zip")
if err := os.WriteFile(zipPath, data, 0644); err != nil {
return nil, err
}
unzipDir := filepath.Join(tmpRoot, "unzip")
if err := os.MkdirAll(unzipDir, 0755); err != nil {
return nil, err
}
// gulu.Zip.Unzip 已内置 zip-slip 路径穿越防护
if err := gulu.Zip.Unzip(zipPath, unzipDir); err != nil {
return nil, errors.New("unzip failed: " + err.Error())
}
skillDirs := findSkillDirs(unzipDir)
if len(skillDirs) == 0 {
return nil, errors.New("no SKILL.md found in the archive")
}
return installSkillDirs(skillDirs, unzipDir)
}
// findSkillDirs 在解压根下查找含 SKILL.md 的 skill 目录,返回相对 root 的路径。
// 递归下钻以兼容任意包裹层(codeload 会把仓库内容包在 <repo-name>/ 下),
// 但一旦某个目录被认定为 skill(直接含 SKILL.md)就停止下钻,避免误入 skill 内部的
// references/scripts 等子目录。识别的结构:
// - SKILL.md 直接在 root(无包裹)
// - <wrap>/SKILL.md(单层或多层包裹的单 skill)
// - <wrap>/skills/<name>/SKILL.md(集合仓库,wrap 可有可无)
func findSkillDirs(root string) []string {
if gulu.File.IsExist(filepath.Join(root, "SKILL.md")) {
return []string{"."}
}
return findSkillDirsRecursive(root, root)
}
View on GitHub (pinned to 251596fc0d)
Solutions
- Ensure the source repository contains a SKILL.md at its root, in a wrapper dir, or under skills/<name>/.
- Rename the skill manifest to exactly SKILL.md (case-sensitive).
- Move SKILL.md out of skipped directories (.github, node_modules, .git, .idea).
- For a single-file skill, use the raw SKILL.md URL instead of a zip.
Example fix
// before — repo has skill.md (lowercase) and is unzipped
// after — rename the manifest to SKILL.md in the source repo, then:
util.InstallSkill("owner/repo") Defensive patterns
Strategy: validation
Validate before calling
// before offering install, validate the repo layout remotely if possible // ensure a SKILL.md exists at root, <wrap>/, or <wrap>/skills/<name>/
Prevention
- Name the manifest exactly SKILL.md (case-sensitive).
- Do not place SKILL.md under .github, node_modules, .git, or .idea — these are skipped.
- Use the raw SKILL.md URL for single-file skills that have no wrapper repo.
When it happens
Trigger: The repository/archive does not contain a SKILL.md at any expected location; the skill file is named differently (skill.md, README.md); SKILL.md is nested under a skipped directory (.github, node_modules, .git, .idea).
Common situations: Installing a generic repo that is not a skill; the skill file uses a non-standard name; the SKILL.md is under node_modules or .github which findSkillDirs deliberately skips.
Related errors
- no valid skill installed
- marketplace package manifest must be at the archive root or
- unzip failed: %s
- SKILL.md frontmatter missing 'name' field
- marketplace package manifest not found or invalid
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/8fa6866b882a8fbc.
Report an issue: GitHub.