AlistGo/alist · error
res.Status()
Error message
res.Status()
What it means
toErr is the generic resty-response-to-error converter for the GitHub driver's non-2xx API replies. It tries to unmarshal the body into ErrResp to append GitHub's 'message' field; when the body is not valid JSON (empty body, HTML error page, plain-text proxy response) it degrades to returning errors.New(res.Status()), i.e. the bare status line such as '403 Forbidden'.
Source
Thrown at drivers/github/util.go:44
TargetPath string
}
func getMessage(tmpl *template.Template, vars *MessageTemplateVars, defaultOpStr string) (string, error) {
sb := strings.Builder{}
if err := tmpl.Execute(&sb, vars); err != nil {
return fmt.Sprintf("%s %s %s", vars.UserName, defaultOpStr, vars.ObjPath), err
}
return sb.String(), nil
}
func calculateBase64Length(inputLength int64) int64 {
return 4 * ((inputLength + 2) / 3)
}
func toErr(res *resty.Response) error {
var errMsg ErrResp
if err := utils.Json.Unmarshal(res.Body(), &errMsg); err != nil {
return errors.New(res.Status())
} else {
return fmt.Errorf("%s: %s", res.Status(), errMsg.Message)
}
}
// Example input:
// a = /aaa/bbb/ccc
// b = /aaa/b11/ddd/ccc
//
// Output:
// ancestor = /aaa
// aChildName = bbb
// bChildName = b11
// aRest = bbb/ccc
// bRest = b11/ddd/ccc
func getPathCommonAncestor(a, b string) (ancestor, aChildName, bChildName, aRest, bRest string) {
a = utils.FixAndCleanPath(a)
b = utils.FixAndCleanPath(b)View on GitHub (pinned to 843d9dc814)
Solutions
- Inspect the status: 403 -> check X-RateLimit-* headers and honor Retry-After; 5xx -> retry with backoff later
- Confirm the token is valid and has the needed scopes (401/403)
- If behind a proxy, ensure it forwards GitHub responses untouched
- Retry the operation after the wait window; the failure is usually transient
Defensive patterns
Strategy: retry
Validate before calling
// Check rate limits before heavy operations
res, _ := client.R().SetContext(ctx).Get("https://api.github.com/rate_limit")
if res.StatusCode() == 200 {
var rl struct{ Rate struct{ Remaining int; Reset int64 } }
_ = utils.Json.Unmarshal(res.Body(), &rl)
if rl.Rate.Remaining < 10 { return fmt.Errorf("rate limit nearly exhausted; resets at %d", rl.Rate.Reset) }
} Try / catch
err := someGithubCall()
if err != nil {
msg := err.Error()
switch {
case strings.Contains(msg, "403"): return fmt.Errorf("rate-limited or forbidden: %w", err)
case strings.Contains(msg, "5"): time.Sleep(30 * time.Second); return someGithubCall()
}
return err
} Prevention
- Authenticate all API traffic — authorized limits are 5-30x higher
- Cache tree/list responses to reduce call volume
- Honor Retry-After headers on 403/429
- Treat bare status-line errors as a signal the body was non-JSON (proxy/outage) and inspect headers
When it happens
Trigger: Any GitHub REST call made through resty that returns an error status with a non-JSON body: 502/504 HTML from a gateway, empty bodies on 403 secondary-rate-limit, corporate proxy interception, or GitHub outage pages.
Common situations: Primary or secondary rate limits (GitHub sometimes omits the JSON body), GitHub incidents, requests routed through a reverse proxy that rewrites error responses.
Related errors
- res.Status
- rename failed with status %d
- missing cookie or qrcode account
- not get file info
- chunkNum invalid
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/d4b5cac30d2d9512.
Report an issue: GitHub.