siyuan-note/siyuan · error

GitHub API returned status %d

Error message

GitHub API returned status %d

What it means

getGitHubJSON is the shared HTTP helper for GitHub API calls in the OIDC GitHub flow. It rejects any response whose status code is outside 2xx with this formatted error carrying the numeric status. Callers wrap it (e.g. load GitHub user failed) but the status number here identifies the actual upstream rejection.

Source

Thrown at kernel/model/oidc_provider/provider.go:204

	}
	return user, nil
}

func getGitHubJSON(ctx context.Context, client *http.Client, endpoint string, target any) error {
	request, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, nil)
	if err != nil {
		return err
	}
	request.Header.Set("Accept", "application/vnd.github+json")
	request.Header.Set("X-GitHub-Api-Version", "2022-11-28")
	request.Header.Set("User-Agent", "SiYuan")
	response, err := client.Do(request)
	if err != nil {
		return err
	}
	defer response.Body.Close()
	if response.StatusCode < http.StatusOK || response.StatusCode >= http.StatusMultipleChoices {
		return fmt.Errorf("GitHub API returned status %d", response.StatusCode)
	}
	decoder := json.NewDecoder(io.LimitReader(response.Body, 1024*1024))
	decoder.UseNumber()
	return decoder.Decode(target)
}

func contains(values []string, target string) bool {
	for _, value := range values {
		if value == target {
			return true
		}
	}
	return false
}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Map the status: 401 - re-authenticate (token invalid); 403 - check scopes or rate limit headers; 404 - verify app configuration; 5xx - retry later
  2. Ensure requested scopes include read:user and user:email for the /user and /user/emails endpoints
  3. If rate limited, wait until the X-RateLimit-Reset time or reduce request volume from that egress IP
  4. Verify no proxy is rewriting the response (check for HTML error pages via curl from the kernel host)
  5. Retry the login flow once GitHub status is healthy (check www.githubstatus.com)
Defensive patterns

Strategy: try-catch

Try / catch

if err := getGitHubJSON(ctx, client, url, &target); err != nil {
    var se interface{ Error() string }
    if errors.As(err, &se) && strings.Contains(se.Error(), "status 403") {
        // inspect X-RateLimit-Reset and back off before retrying
    }
    return err
}

Prevention

When it happens

Trigger: Any GitHub API call in exchangeGitHubClaims (api.github.com/user or api.github.com/user/emails) returning 401 (bad token), 403 (forbidden scopes or rate limit), 404 (resource/app misconfigured), or 5xx (GitHub outage).

Common situations: Access token expired or revoked (401); OAuth app scopes too narrow (403); shared-IP rate limiting (403); GitHub brownouts/deprecations; corporate egress proxy returning 407/502.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/c997046c84d72a73. Report an issue: GitHub.