AlistGo/alist · error
delete offline tasks failed: %s
Error message
delete offline tasks failed: %s
What it means
Thrown by GuangYaPan's DeleteOfflineTasks after POST /cloudcollection/v2/delete_task succeeds at the HTTP layer but returns a non-success Msg. The server processed (or rejected) the batch deletion of task IDs; the trimmed server message is included. Note deletion is all-or-nothing from the caller's view — partial server-side success is not distinguishable here.
Source
Thrown at drivers/guangyapan/offline.go:129
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
}
if !isSuccessMsg(resp.Msg) {
return fmt.Errorf("delete offline tasks failed: %s", strings.TrimSpace(resp.Msg))
}
return nil
}
func (d OfflineResolveData) defaultName(fileURL string) string {
if d.BTResInfo != nil && strings.TrimSpace(d.BTResInfo.FileName) != "" {
return strings.TrimSpace(d.BTResInfo.FileName)
}
u, err := url.Parse(fileURL)
if err == nil {
name := strings.TrimSpace(stdpath.Base(u.Path))
if name != "" && name != "." && name != "/" {
if decoded, err := url.PathUnescape(name); err == nil {
name = decoded
}
return name
}
}View on GitHub (pinned to 843d9dc814)
Solutions
- Inspect resp.Msg for the server's reason (already-deleted vs. auth vs. batch-size errors).
- Re-list tasks (ListOfflineTasks) and filter out IDs that no longer exist before retrying the delete.
- Treat 'already deleted/not found' style messages as success (idempotent delete) at the caller level if the workflow allows.
- Split very large taskIDs batches into smaller chunks if the msg indicates a limit.
Example fix
// before
if err := d.DeleteOfflineTasks(ctx, taskIDs, true); err != nil { return err }
// after
if err := d.DeleteOfflineTasks(ctx, taskIDs, true); err != nil {
if strings.Contains(err.Error(), "not exist") { // server-specific idempotency marker
return nil // already gone; treat as success
}
return err
} Defensive patterns
Strategy: validation
Validate before calling
// prune IDs against a fresh listing before deleting
list, err := d.ListOfflineTasks(ctx, "", 100)
if err != nil { return err }
live := make(map[string]bool)
for _, t := range list { live[t.TaskID] = true }
valid := taskIDs[:0]
for _, id := range taskIDs { if live[id] { valid = append(valid, id) } }
if len(valid) == 0 { return nil } Try / catch
if err := d.DeleteOfflineTasks(ctx, ids, del); err != nil {
if strings.Contains(err.Error(), "delete offline tasks failed") && isNotFoundMsg(err) {
return nil // idempotent
}
return err
} Prevention
- Re-list before delete to drop already-removed IDs
- Guard against double-submit in UIs
- Batch deletes within provider limits
When it happens
Trigger: Passing task IDs that were already deleted, expired, or belong to another account; sending a batch larger than the v2 endpoint accepts; token revoked between the listing call and the delete call.
Common situations: UI deletes a task twice (double-click, stale list refresh); concurrent deletion from another client between list and delete; retrying a delete that actually succeeded (the first attempt's response was lost).
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/483c268050120c37.
Report an issue: GitHub.