siyuan-note/siyuan · error
download failed (tried main and master): %v
Error message
download failed (tried main and master): %v
What it means
Thrown by downloadSkillSource after the codeload zip download fails on the 'main' branch and the automatic fallback to 'master' also fails. The error wraps the original main-branch error. It means the repository could not be fetched as a zip from either default branch name.
Source
Thrown at kernel/util/skill.go:392
return nil, "", fmt.Errorf("invalid download URL: %s", src.downloadURL)
}
if cerr := CheckHostSSRF(u.Hostname()); cerr != nil {
return nil, "", cerr
}
data, contentType, err = fetchBytes(src.downloadURL)
if err == nil {
return data, contentType, nil
}
// codeload main 分支 404 时回退 master
if src.isZip && src.branch == "main" {
ownerRepo := strings.TrimPrefix(strings.TrimPrefix(src.downloadURL, "https://codeload.github.com/"), "http://codeload.github.com/")
ownerRepo = strings.TrimSuffix(ownerRepo, "/zip/refs/heads/main")
fallback := codeloadSource(ownerRepo, "master")
data, contentType, ferr := fetchBytes(fallback.downloadURL)
if ferr != nil {
return nil, "", fmt.Errorf("download failed (tried main and master): %v", err)
}
return data, contentType, nil
}
return nil, "", err
}
// fetchBytes 执行带大小限制的 GET
func fetchBytes(rawURL string) (data []byte, contentType string, err error) {
resp, err := httpclient.NewBrowserRequest().Get(rawURL)
if err != nil {
return nil, "", errors.New("download failed: " + err.Error())
}
defer resp.Body.Close()
if resp.StatusCode >= 400 {
return nil, "", fmt.Errorf("download failed: HTTP %d", resp.StatusCode)
}
View on GitHub (pinned to 251596fc0d)
Solutions
- Provide an explicit branch via the tree/<branch> URL form: https://github.com/owner/repo/tree/develop.
- Verify the owner/repo spelling and that the repo is public.
- Retry after confirming network access to codeload.github.com.
- For private repos, use a release asset or raw URL accessible with the available credentials.
Example fix
// before — default-branch autodetect fails
util.InstallSkill("owner/repo")
// after — pin the actual branch
util.InstallSkill("https://github.com/owner/repo/tree/develop") Defensive patterns
Strategy: validation
Validate before calling
// prefer an explicit branch to avoid main/master guessing
if isOwnerRepoShorthand(src) {
// prompt user or default to a known branch via tree/<branch> URL
src = "https://github.com/" + src + "/tree/main"
} Try / catch
// retry once, then suggest pinning a branch
res, err := util.InstallSkill(src)
if err != nil && strings.Contains(err.Error(), "tried main and master") {
return fmt.Errorf("could not fetch repo on main or master; specify the branch, e.g. https://github.com/%s/tree/<branch>", src)
} Prevention
- If a repo's default branch is not main/master, install via the tree/<branch> URL form.
- Confirm the repository is public before installing.
- For private repos, use an accessible release asset or raw URL.
When it happens
Trigger: Installing owner/repo shorthand or a bare github.com repo whose default branch is neither 'main' nor 'master' (e.g. 'develop', 'trunk'); the repo does not exist; codeload.github.com is unreachable; the repo is private and requires auth.
Common situations: Repository uses a non-standard default branch; 404 because owner/repo is wrong; rate-limited or blocked by GitHub; private repo without credentials; transient network outage.
Related errors
- download custom emoji failed with status %d
- get bazaar package failed, please check your network
- get checksum manifest failed: %d
- unsupported skill source (content-type: %s); expected a zip
- invalid github URL: %s
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/0f64d19e9c9dd11c.
Report an issue: GitHub.