AlistGo/alist · error
%s:%s
Error message
%s:%s
What it means
This is Dropbox driver's generic API error formatter: the request returned non-200, it was not an auth error (or a token refresh was already retried), so it surfaces the parsed Dropbox error tag and error_summary joined as "tag: summary". The two fields come from Dropbox's v2 error JSON, where Error is the short tag (e.g. path/conflict) and ErrorSummary the human-readable detail.
Source
Thrown at drivers/dropbox/util.go:85
res, err := req.Execute(method, d.base+uri)
if err != nil {
return nil, err
}
log.Debugf("[dropbox] request (%s) response: %s", uri, res.String())
isRetry := len(retry) > 0 && retry[0]
if res.StatusCode() != 200 {
body := res.String()
if !isRetry && (utils.SliceMeet([]string{"expired_access_token", "invalid_access_token", "authorization"}, body,
func(item string, v string) bool {
return strings.Contains(v, item)
}) || d.AccessToken == "") {
err = d.refreshToken()
if err != nil {
return nil, err
}
return d.request(uri, method, callback, true)
}
return nil, fmt.Errorf("%s:%s", e.Error, e.ErrorSummary)
}
return res.Body(), nil
}
func (d *Dropbox) list(ctx context.Context, data base.Json, isContinue bool) (*ListResp, error) {
var resp ListResp
uri := "/2/files/list_folder"
if isContinue {
uri += "/continue"
}
_, err := d.request(uri, http.MethodPost, func(req *resty.Request) {
req.SetContext(ctx).SetBody(data).SetResult(&resp)
})
if err != nil {
return nil, err
}
return &resp, nil
}View on GitHub (pinned to 843d9dc814)
Solutions
- Decode the error_summary in the message — it names the exact problem (e.g. missing_scope tells you which scope to add in the App Console)
- For missing_scope: add the scope in the Dropbox App Console and re-authorize to get a new refresh token
- For too_many_requests/rate_limit: back off and retry with exponential delay
- For path errors: re-list the parent to refresh ids/paths before retrying the operation
Defensive patterns
Strategy: retry
Try / catch
_, err := d.request(uri, method, cb)
if err != nil {
if strings.Contains(err.Error(), "too_many_requests") || strings.Contains(err.Error(), "rate_limit") {
time.Sleep(backoff.Next()) // exponential backoff, then retry
return d.request(uri, method, cb)
}
if strings.Contains(err.Error(), "missing_scope") {
return fmt.Errorf("dropbox app lacks scope; update App Console: %w", err)
}
return err
} Prevention
- Match app scopes to every driver operation (read AND write scopes for two-way mounts)
- Cache listings to stay under Dropbox rate limits
- Handle 409 path errors by refreshing path state rather than blind retries
When it happens
Trigger: Any non-auth Dropbox API failure after the single retry-on-refresh: 400 from malformed parameters, 409 path_lookup/not_found or path/conflict on file operations, 429 rate limiting (too_many_requests), 403 from insufficient app permissions (e.g. missing files.metadata.read scope).
Common situations: Missing OAuth scopes for the operation attempted (app has files.content.read but driver tries a write); operating on a file/folder that was moved or deleted; hammering the API and hitting rate limits; accessing team content without the team scopes.
Related errors
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/e4c4764a458d22d1.
Report an issue: GitHub.