siyuan-note/siyuan · error
GitHub releases are empty
Error message
GitHub releases are empty
What it means
After a 200 response from the GitHub releases API, fetchGitHubReleases checks that the decoded releases array is non-empty before populating the cache. If GitHub returns 200 with zero releases (empty array), the call fails with 'GitHub releases are empty' rather than proceeding with no selectable release.
Solutions
- Retry the check later or with force=true once GitHub status (https://www.githubstatus.com) is healthy
- Inspect https://api.github.com/repos/siyuan-note/siyuan/releases from the machine to see the raw body — if it is not a releases array, a proxy is altering the response
- Use the stable channel instead, which does not depend on the GitHub releases API
- Clear any interfering corporate proxy/DLP that rewrites GitHub API responses
Defensive patterns
Strategy: retry
Validate before calling
resp, _ := http.Get(githubReleasesURL) body, _ := io.ReadAll(resp.Body) var arr []json.RawMessage looksLikeArray := json.Unmarshal(body, &arr) == nil && len(arr) > 0
Type guard
func nonEmptyReleases(b []byte) bool {
var arr []*githubRelease
return json.Unmarshal(b, &arr) == nil && len(arr) > 0
} Try / catch
releases, err := fetchGitHubReleases(ctx)
if err != nil {
if cachedGitHubReleases != nil { releases = cachedGitHubReleases } // last-known-good fallback
} Prevention
- Verify GitHub status before debugging; empty 200 bodies occur during incidents
- Check whether a proxy/DLP appliance strips or rewrites response bodies
- Treat a persistent empty-array response as an upstream API problem, not a client bug
- Keep the previous release list as a fallback for update decisions
When it happens
Trigger: GET on the releases endpoint returning HTTP 200 with an empty JSON array — the repo has no published releases visible to the request, or the response body failed to unmarshal into releases leaving the slice empty.
Common situations: GitHub API outage/degraded mode returning empty payloads; a proxy or firewall stripping the response body; unexpected response shape (e.g. an error object) that SetSuccessResult cannot decode, silently yielding zero items.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- empty catalog
- get GitHub releases failed
- load GitHub user failed
- access to private/internal IP is prohibited
- access to private/internal IP is prohibited
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/18ad91023a6547ab.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/updater_release.go:252
func fetchGitHubReleases(ctx context.Context) ([]*githubRelease, error) {
releases := []*githubRelease{}
request := httpclient.NewCloudRequest30s().
SetContext(ctx).
SetHeader("Accept", "application/vnd.github+json").
SetHeader("X-GitHub-Api-Version", "2022-11-28").
SetSuccessResult(&releases)
response, err := request.Get(githubReleasesURL)
if err != nil {
logging.LogErrorf("get GitHub releases failed: %s", err)
return nil, err
}
if 200 != response.StatusCode {
err = fmt.Errorf("get GitHub releases failed: %d", response.StatusCode)
logging.LogError(err.Error())
return nil, err
}
if 0 == len(releases) {
return nil, errors.New("GitHub releases are empty")
}
githubReleasesLock.Lock()
cachedGitHubReleases = releases
githubReleasesCacheTime = time.Now().Unix()
githubReleasesLock.Unlock()
return releases, nil
}
func selectGitHubRelease(releases []*githubRelease, channel string) *githubRelease {
var selected *githubRelease
for _, release := range releases {
if nil == release || release.Draft || !isReleaseAllowed(channel, release.TagName) {
continue
}
if nil == selected || 0 < semver.Compare(normalizeReleaseVersion(release.TagName), normalizeReleaseVersion(selected.TagName)) {
selected = release
}View on GitHub (pinned to 9f775e8a12)