AlistGo/alist · error
list offline tasks failed: %s
Error message
list offline tasks failed: %s
What it means
Thrown by GuangYaPan's ListOfflineTasks after the cloud-collection list API (POST /cloudcollection/v1/list_task) returns HTTP 200 but a Msg field that is not a success marker. The HTTP transport succeeded, so the failure is at the application/protocol level: the server rejected the listing request. The raw server message is embedded via %s after trimming whitespace.
Source
Thrown at drivers/guangyapan/offline.go:109
if len(taskIDs) > 0 {
body["taskIds"] = taskIDs
}
if len(statuses) > 0 {
body["status"] = statuses
}
if cursor = strings.TrimSpace(cursor); cursor != "" {
body["cursor"] = cursor
}
if pageSize > 0 {
body["pageSize"] = pageSize
}
var resp offlineListResp
if err := d.postAPI(ctx, "/cloudcollection/v1/list_task", body, &resp); err != nil {
return nil, err
}
if !isSuccessMsg(resp.Msg) {
return nil, fmt.Errorf("list offline tasks failed: %s", strings.TrimSpace(resp.Msg))
}
return resp.Data.List, nil
}
func (d *GuangYaPan) DeleteOfflineTasks(ctx context.Context, taskIDs []string, deleteFiles bool) error {
if err := d.ensureAccessToken(ctx); err != nil {
return err
}
if len(taskIDs) == 0 {
return nil
}
var resp offlineDeleteResp
if err := d.postAPI(ctx, "/cloudcollection/v2/delete_task", map[string]any{
"taskIds": taskIDs,
}, &resp); err != nil {
return err
}View on GitHub (pinned to 843d9dc814)
Solutions
- Read the embedded resp.Msg — it is the server's own reason and disambiguates auth vs. param vs. rate-limit failures.
- Re-run ensureAccessToken (or re-login) and retry the list once from the first page with an empty cursor.
- Validate cursor/pageSize inputs: send pageSize only when > 0 and only pass cursors returned by a previous response.
- If msg indicates permission denial, enable/verify the offline-download feature for the account before retrying.
Example fix
// before
list, err := d.ListOfflineTasks(ctx, staleCursor, 0)
if err != nil { return err }
// after
list, err := d.ListOfflineTasks(ctx, "", 100) // restart from first page
if err != nil {
if strings.Contains(err.Error(), "login") { // heuristic on server msg
if rerr := d.ensureAccessToken(ctx); rerr != nil { return rerr }
list, err = d.ListOfflineTasks(ctx, "", 100)
}
if err != nil { return err }
} Defensive patterns
Strategy: retry
Try / catch
if _, err := d.ListOfflineTasks(ctx, cursor, size); err != nil {
if strings.Contains(err.Error(), "list offline tasks failed") {
// one retry from first page with fresh token
_ = d.ensureAccessToken(ctx)
_, err = d.ListOfflineTasks(ctx, "", size)
}
if err != nil { return err }
} Prevention
- Only pass cursors obtained from the immediately previous response
- Re-verify the access token before long pagination walks
- Cap pageSize to provider-documented limits
When it happens
Trigger: Calling ListOfflineTasks with a cursor from an expired/invalid pagination session, a pageSize the backend rejects, an access token that was valid at ensureAccessToken time but revoked before the call, or when the account has no offline-download permission on the cloudcollection endpoint.
Common situations: Stale cursor reused after a long pagination walk; token invalidated by logging in on another device; the guangyapan offline API changed its response contract between app versions; rate limiting reported as a non-success msg.
Related errors
- offline url is empty
- create offline task failed: empty task id
- GuangYaPan offline download only supports GuangYaPan destina
- failed
- canceled
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/2d0f33b55b5ea522.
Report an issue: GitHub.