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

  1. Read the embedded resp.Msg — it is the server's own reason and disambiguates auth vs. param vs. rate-limit failures.
  2. Re-run ensureAccessToken (or re-login) and retry the list once from the first page with an empty cursor.
  3. Validate cursor/pageSize inputs: send pageSize only when > 0 and only pass cursors returned by a previous response.
  4. 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

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


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/2d0f33b55b5ea522. Report an issue: GitHub.